(前期声明:本文只是作者想要总结的知识点,不保证读者能看懂,只是给作者复习的时候能利用,但是还是想要把这些分享出来。另链表的学习来源是这篇博客 关于链表,看这一篇就够了!(新手入门))
目录
First首先就是链表的结构知识
这里的链表是带有头节点的即 头指针->头结点->首元结点->....
画个图就知道了(头指针就只是一个指向头结点的一个指针内容 8字节大小是看自己的电脑设备的操作系统 在64位操作系统就是8字节 )
另外还有头结点不能算是线性表的内容,其数据域的内容其实没什么意义。
从这个角度来看看链表的初始化(这是我要讲的第一个难理解的点)
//算法步骤
//1.先生成新节点作为头节点,用指针L指向头节点 2.头节点指针域为空
Status InitList(LinkList *L)//或者这里写成(LinkList &L)(C++写法)相当于是写成了 Lnode **L
{ //这个L其实就是相当于是头指针
*L=(Lnode *)malloc(sizeof(Lnode));//这里相当于是把Lnode这么大的空间的地址交给了一个指向Lnode类型空间的指针
(*L)->next=NULL;//这里相当于是从L(类似二级指针先用星号指向了链表头节点 然后再用->指向了首节点)
return OK;
}
这只是一个初始化链表的函数
接下来的主函数可以这么写
int main()
{
LinkList L;//LinkList 相当于是 Lnode *(是链表结点的指针表示)
InitList(&L);//这里传递的就是头结点的地址也就是头指针的内容
//在子函数中的形参就好比是头指针,指向的就是头节点(可以理解成二级指针)
return 0;
}
第二个就是在清空链表的子函数上有一些疑问
直接上代码吧!
void ClearList(LinkList *L){
LinkList Curnode,NextNode;//头节点本身也是一个指向Lnode结构体类型的指针
Curnode = (*L)->next;//这里相当于是把首元节点的地址交给了Curnode ||*L->next 指代的就是头节点的指针域储存的内容
while(Curnode){
NextNode = Curnode->next;
free(Curnode);
Curnode = NextNode;
}
//最后还要管理一下头节点的指针域
(*L)->next = NULL;
}
其实我就是想说一下 如何理解Curnode = (*L)->next.(希望自己下一次看的时候能立刻明白这里面的含义)
很明显这里其实就是从二级指针先指向了头结点 (*L)操作 然后又通过一级指针指向了首元结点(但是实际上其实从存储了首结点的地址出发指向了首结点,然后再将首结点结构体中的Next取出来交给了Curnode)
但是 next内容是什么呢? 没错!就是首结点之后的首元结点的地址。
可是Curnode本身就是一个结构体类型的指针变量,这个指针变量储存了首元结点的地址信息。那换句话说就是——Curnode指向了首元结点!(真相只有一个哈哈哈哈哈哈哈哈哈哈哈)
第三个不太好理解的地方是
就是怎么理解类似这样的操作
//头插法插入链表节点 //默认链表本来就是空的但是已经被创立了
void InsertNodeByRear(LinkList *L,int n){
LinkList Curnode = *L;
while(n--){
LinkList p=(LinkList)malloc(sizeof(Lnode));
p->next=NULL;
scanf("%c",&(p->date));
Curnode->next = p;//这两行该怎么理解
Curnode = p;
}
}
不卖关子了,其实我就是想说 链表的本身其实是一串指针所组成的链条。这个链条的每个结点都指向着一个结构体,结构体的内容中就包含有每个结点的下一个结点的信息。所以说在上面这段代码中Curnode->next = p;其实就是两个指针之间的内容传递,即p将其所指向的结点的内容传递给Curnode所指结构体中的next——换句话说就是Curnode的下一个结点就是p所指向的结点。但是实际上这是指针内容(地址信息)之间的交换。实际在操作的过程中还是要通过指针操纵(*)来完成。