喜欢《数据结构》部分笔记的小伙伴可以订阅专栏,今后还会不断更新。
此外,《程序员必备技能》专栏和《程序员必备工具》专栏(该专栏暂未开设)日后会逐步更新,感兴趣的小伙伴可以点一下订阅、收藏、关注!
谢谢大家!
引言
假如有很多个数据元素,怎么把他们存到一个单链表里面
- 初始化一个单链表
- 每次取一个数据元素,插入到表尾/表头
本节讨论带头结点的情况
尾插法建立单链表
具体代码实现:
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
//初始化一个单链表
bool InitList(LinkList &L){
L = (LNode *) malloc (sizeof(LNode)); //分配一个头结点
if(L == NULL) //内存不足,分配失败
return false;
L->next = NULL; //头结点之后暂时没有结点
return true;
}
void test(){
LinkList L;
InitList(L);
//......
}
举例:
初始化单链表
设置变量length
记录链表长度
while 循环{
每次取一个元素e;
ListInsert(L, length+1, e)插到尾部;
length++;
}
这种操作的时间复杂度为: O ( n 2 ) O(n^2) O(n2),还是很高的
其实完全可以采用更好的方法:
设置一个表尾指针r
每次要插入元素的时候只需要对r
进行后插操作就好了[[2.3.2_1 单链表的插入和删除#指定结点的后插操作]]
课本中的代码:
LinkList List_TailInsert(LinkList &L){ 正向建立单链表
int x; //设ElemType为整型
L = (LNode *) malloc (sizeof(LNode)); //建立头结点
LNode *s, *r = L; //r为表尾指针
scanf("%d", &x); //输入结点的值
while(x != 9999){ //输入9999表示结束
s = (LNode *) malloc (sizeof(LNode));
s->data = x;
r->next = s;
r = s; //r指向新的表尾结点
scanf("%d", &x);
}
r->next = NULL; //尾结点指针置空
return L;
}
时间复杂度: O ( n ) O(n) O(n)
头插法
课本中的代码:
LinkList List_HeadInsert(LinkList &L){ //逆向建立单链表
LNode *s;
int x;
L = (LNode *) malloc (sizeof(LNode)); //创建头结点
L->next = NULL; //初始化为空链表
scanf("%d", &x); //输出结点的值
while(x != 9999){ //输入9999表示结束
s = (LNode *) malloc (sizeof(LNode)); //创建新结点
s->data = x;
s->next = L->next;
L->next = s; //将新结点插入表中,L为头指针
scanf("%d", &x);
}
return L;
}
知识回顾和重要考点
头插法、尾插法:
核心就是初始化操作、指定结点的后插操作
尾插法要注意设置一个指向表尾的指针
头插法的重要应用:
链表的逆置(经常考察)