指针

数据结构之链表

雨燕双飞 提交于 2020-01-25 04:46:34
数据需要一块连续的内存空间来存储,对内存的要求比较高。而链表恰恰相反,它并不需要一块连续的内存空间,它通过“ 指针 ”将一组 零散 的内存块串联起来使用。 最常见的链表:单链表、双链表、和循环链表。 单链表 结点 :除了存储数据之外,还要记录链上的下一个节点的地址,如下图,我们把这个记录下个结点地址的指针叫作 后继指针 next 头结点 :用来记录链表的基地址。 尾结点 :指向一个空地址 NULL 针对链表的插入和删除操作,只需考虑相邻结点的指针改变,所以对应的时间复杂度是O(1)。 链表想要随机访问第k个元素,就没有数组那么高效,链表的数据并非连续存储的,所以无法像数组那样,根据首地址和下标通过寻址公式就能直接计算出对应的内存地址,而是要根据指针一个结点一个结点的一次遍历,直到找到相应的结点。需要 O(n)时间复杂度 。 循环链表 是一种特殊的单链表。它和单链表唯一的区别就在尾结点。循环链表的 尾结点指针是指向链表的头结点 。 当处理的数据具有环形结构特点时,就特别适合采用循环链表。 双向链表 双向链表支持双向遍历,它需要额外的两个空间来存储后继结点和前驱结点的地址。 时空替换思想 :“用空间换时间” 与 “用时间换空间” 当内存空间充足的时候,如果我们更加追求代码的执行速度,我们就可以选择空间复杂度相对较高,时间复杂度小相对较低的算法和数据结构,缓存就是空间换时间的例子

数据结构-链表

帅比萌擦擦* 提交于 2020-01-25 04:45:25
数组需要一块连续的内存用来存储数据,而链表恰恰相反,它并不需要一块连续的内存,它通过指针将不连续的内存块串起来。 链表结构很多,我们说下最常见的,单链表,双向链表和循环链表。 我们先看比较简单的 单链表 如上图可以看出来,图中的每个节点不仅需要存储数据,还需要记录一个指向下一个节点的指针,如图所示,我们把记录下一个节点的指针叫做后继指针 next 图中有两个节点比较特殊第一个节点我们叫做头节点,最后一个节点我们叫做尾结点,头节点记录了这个链表的基地址,尾节点的指针不是指向一个节点,而是指向一个空地址NULL。 我们知道在数组的插入和删除操作后,为了保持连续内存的特点需要搬移大量数据,而在链表中我们不需要保持连续内存的结构,所有我们在链表中插入和删除操作时时间要比在数组中操作删除添加速度快, 针对链表的插入和删除操作可以看下图 但是有利就有弊,在链表中查询数据的时候就没有数组那么快了,在数组中可以首地址和下标可以很快查出来,因为是连续的,但是在链表中由于不是连续的,我们就需要根据指针节点一个一个遍历才能查询出需要的数据。 接下来我们看下循环链表,其实循环链表就是一种特殊的单链表 循环链表就是尾结点指向链表的头节点,而不是指向一个空值,有点就是从链表尾部查询到链表头部很方便,在处理某些特殊的数据结构时很有用处。 最后我们在看下 双向链表 单链表只有一个方向

数据结构基础温故-1.线性表(下)

痴心易碎 提交于 2020-01-25 04:39:08
在 上一篇 中,我们了解了单链表与双链表,本次将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表(circular linked list)。 一、循环链表基础 1.1 循环链表节点结构   循环链表和单链表的主要差异就在于 循环的判断条件 上,原来是判断p.next是否为空,现在则是p.next不等于头结点,则循环未结束。 1.2 循环链表的O(1)访问时间   在单链表中,有了头结点,我们可以在O(1)时间访问到第一个节点,但如果要访问最后一个节点却需要O(n)的时间,因为我们需要对整个链表进行一次遍历。在循环链表中,我们可以借助尾节点来实现,即不用头指针,而是 用指向终端结点的尾指针来表示循环链表 ,这时候无论是查找第一个节点还是最后一个节点都很方便,可以控制在O(1)的时间内,如下图所示。   从上图中可以看到,终端结点用尾指针(tail)指示,则查找终端结点是O(1),而开始结点,其实就是tail.Next,其时间复杂也为O(1)。由此也可以联想到,在合并两个循环链表时,只需要修改两个链表的尾指针即可快速地进行合并。 二、循环链表实现 2.1 循环链表节点的定义实现 public class CirNode<T> { public T Item { get; set; } public

如何使用指针从函数返回一个数组

﹥>﹥吖頭↗ 提交于 2020-01-25 03:52:11
#include <iostream> #include <stdlib.h> using namespace std; //这里function是一个函数,它返回一个指针,该指针指向的是包含20个int类型元素的数组。 int (*function())[20] { int i=0; int (*p)[20];//声明一个指向20个元素的指针; p=(int(*)[20])calloc(20,sizeof(int)); //或者p=(int (*)[20])malloc(sizeof(int)*20); if(!p)//内存不够; { cout<<"the memory is not enough!"<<endl; return NULL; } for(i=0;i<20;i++) (*p)[i]=i+5; return p; } int main() { int (*result)[20]; result=function(); if(result) { cout<<result[7]<<endl;//这样访问结果,应该输出8。 free(result); } system("pause"); return 0; } 来源: CSDN 作者: 少林达摩祖师 链接: https://blog.csdn.net/special00/article/details/103960918

const限定符与指针

[亡魂溺海] 提交于 2020-01-25 02:40:49
const限定符与指针 const 作用 如果一个变量使用const修饰,则表明该变量只能被访问,而不能被修改(const == “readonly”)。 # include "stdio.h" int main ( void ) { const int a = 0 ; int b = 0 ; a = 1 ; return 0 ; } 编译报错 error: assignment of read-only variable ‘a’ a = 1; 和指针结合情况一 const int * a; int const * a; 这两个都是表达 a 是指向const int 型的指针,a所指向的内存单元的内容不能改变,但指针 a 可以改变,代码如下 const int * a = NULL ; //int const * a; int b = 1 ; ; a = & b ; printf ( "const point test a = &b %d\n" , * a ) ; * a = 100 ; printf ( "const point test a = 100 %d\n" , * a ) ; return 0 ; 编译信息如下: error: assignment of read-only location ‘*a’ *a = 100; 和指针结合情况二 int * const a;

C语言文件操作总结

泪湿孤枕 提交于 2020-01-25 01:22:24
文件的打开操作 fopen 打开一个文件,操作文件指针FILE *       文件的关闭操作 fclose 关闭一个文件       文件的读写操作 fgetc 从文件中读取一个字符               fputc 写一个字符到文件中去               fgets 从文件中读取一个字符串               fputs 写一个字符串到文件中去               fprintf 往文件中写格式化数据               fscanf 格式化读取文件中数据               fread 以二进制形式读取文件中的数据               fwrite 以二进制形式写数据到文件中去               getw 以二进制形式读取一个整数               putw 以二进制形式存贮一个整数     文件状态检查函数 feof 文件结束               ferror 文件读/写出错               clearerr 清除文件错误标志               ftell 了解文件指针的当前位置       文件定位函数 rewind 反绕               fseek 随机定位 一、文件打开关闭 (一)文件打开  1. 函数原型 FILE *fopen(char

链表面试常见题目总结

独自空忆成欢 提交于 2020-01-25 01:10:55
1.反转链表:头插法, 2.合并两个有序链表 3.链表倒数第k个节点:连个节点一个先走 k步,然后两个一起走,走到第一个节点.next为null 4.从尾到头打印 链表,借助栈或者递归 5.复杂链表复制,1)借助map存储,O(n)空间,2)把新节点穿在老节点之后,再删除老节点 6.BST转链表,遍历parent节点 7.两个链表第一个公共 节点,先遍历两个链表,长度1-长度2=差值,长的链表先走差值步,然后两个链表一起走,相同节点即为第一个 。 8.两个链表是否有环,快慢指针,一个走一步,一个走两步。相等有环。交点处,快 指针回到头节点,慢指针在交点处 ,两个指针每次走一步,相交即为环 的入口。在环的入口处,快指针不动,慢 指针每次走一步,快慢 指针再次相遇,慢指针走的步数,即为环的大小。 9.两个链表是否 相交 ,求交点 ,同7 10.O(1)空间删除节点 :将待删除节点.next的值赋给自己,然后删除待删除节点 .next 11.单链表排序,快排 12.约瑟夫环。经典问题 来源: CSDN 作者: Keal、 链接: https://blog.csdn.net/qq422243639/article/details/104079507

C语言指针笔记一

假装没事ソ 提交于 2020-01-25 00:45:23
其实以前在学校也学过一点点C,不过那都是好久之前的事情了。最近因为要上 C++ 的课程,所以必须要熟练C基础,指针又要重新复习一遍了。 下面这幅图很简单的表现了变量和指针的关系 指针变量p也是在内存中占用了地址的,通过&p可以获取到 其实可以很形象的表示:*p是连接变量a的桥梁,有了这个链接,我们就可以访问到变量a的内容:*p = a,而变量p本身存放的是a的地址。 来源: CSDN 作者: 风楚颜 链接: https://blog.csdn.net/maybe_frank/article/details/103835499

C语言指针

此生再无相见时 提交于 2020-01-25 00:32:54
指针 指针 指针变量的定义语法 取地址运算符:& 间接运算符:* 空指针 void指针 malloc函数 const 常量指针 常量指针 常量指针变量 指针常量 指针与数组 通过指针变量访问数组 数组指针 指针数组 指向函数的指针(函数指针) 指针 指针 就是内存地址,指针变量就是存储地址的变量. 作用: 使用指针可提高程序的编译效率和执行速度,是程序更加简洁;通过传递指针参数,使被调用函数可向主调函数返回除正常的返回值之外的其他数据,从而达到两者之间的双向通信;还有一些任务,如动态内存分配,没有指针是无法执行的;指针还用于表示和实现各种复杂的存储结构(如链表),从而为编写出更高质量的程序奠定基础;利用指针可以直接操纵内存地址,从而可以完成和汇编语言类似的工作. c语言提供 两种指针运算符 : * 和 & . 指针变量的定义语法 指针变量的定义语法: 数据类型 * 变量名 [ = 初值 ]; 指针变量定义时,数据类型并不是指指针变量的数据类型,而是其所指目标对象的数据类型.例如: int* p ;定义 p 是指针变量,可以存储 int 型变量的地址,p 变量的类型是 int*,而不是 int.这是告诉编译器, p 变量只能存储整型变量的空间地址,不能存储其他类型空间的地址 取地址运算符:& p = &a; 表明得到整型变量 a 的地址,并把该地址存入指针变量 p 中

单继承,多继承,虚拟继承,sizeof大小

冷暖自知 提交于 2020-01-24 23:48:34
1. 题目 #include<iostream>using namespace std;class S {};class A:S { virtual void fun() { ; }};class B:A { virtual void fun() { ; }};class C:B { virtual void fun() { ; }};class M { virtual void fun() {}};class N { virtual void fun() {}};class P:M,N { virtual void fun() {}};//------------------------------class T_S {};class T_A:virtual T_S { virtual void fun() { ; }};class T_B:virtual T_A { virtual void fun() { ; }};class T_C:virtual T_B { virtual void fun() { ; }};class T_M { virtual void fun() {}};class T_N { virtual void fun() {}};class T_P:virtual T_M,T_N { virtual void fun() {}};int main() {