最近在听王卓老师的数据结构课,其中讲到了单链表的实现。
她的上课课件上采用的类C语言的代码,所以我在实践中使用C语言来实现,也遇到了不少问题。
这篇文章主要是记录一下我所遇到的一些问题。
单链表的相关知识
单链表作为线性表链式结构的实现,它的逻辑结构与物理结构不同,其存取方式属于顺序存取
各结点由两个域组成
数据域:存储元素数值数据
指针域:存储直接后继结点的存储位置
![](https://img-blog.csdnimg.cn/img_convert/5297dbdbdb34c2a823f7d2a3e1cd8df0.png)
首元结点:是指存储第一个数据元素a1的结点
头结点:在首源结点之前附设的一个结点,其指针域指向首元结点
头指针:是指向链表中的第一个结点的指针
单链表的存储结构
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList
//LinkList 一般用于定义头指针,LNode 一般用于定义具体的结点
单链表的部分算法实现
单链表的初始化
类C语言的描述
![](https://img-blog.csdnimg.cn/img_convert/802ac3108e501924ff9cf9d1b1edb499.png)
分析算法
根据上图描述,L应该为引用变量,即形参变化实参也会发生变化,根据我之前实现顺序表的经验,这里一定是要传入一个指针变量的,但是考虑到这里的LinkList类型已经是指针类型了,所以在这里会纠结于是传入一个LinkList的变量,还是LinkList的指针变量。
尝试实现
int InitList_L(LinkList L){
L = (LinkList)malloc(sizeof(LNode));
if(!L) return ERROR;
L.next = NULL;
return OK;
}
int main(void){
LinkList L;
int Init = InitList_L(L);
printf("Init:%d\n",Init);
return 0;
}
这样的写法看上去没问题,实际运行也能返回OK(1),但是再对L调用其他方法,程序会直接结束。
反思问题
这样的写法其实是一个很基础的错误,传值的错误,也是对指针还不够熟练的表现。
这里L只是将它的值,也就是其指向的地址,传入到函数中了,但是并不会修改L原本存放的地址。
回想到刚接触指针时所学的案例--交换两个变量的值,如果想改变这两个变量的值,就必须传入它们的地址,通过指针存放它们的地址,找到变量改变值。
所以在这里,函数中申请的空间的首地址,如何赋给L,就必须要传入L的地址。
最终实现
int InitList_L(LinkList *L){
*L = (LinkList)malloc(sizeof(LNode));
if(!*L) return ERROR;
(**L).next = NULL;
return OK;
}
int main(void){
LinkList L;
int Init = InitList_L(&L);
printf("Init:%d\n",Init);
return 0;
}
单链表的创建--头插法
未完待续。。。