- 数组:一段连续的内存空间
顺序存储
。 - 链表:一种新的数据组织形式。(链式)
typedef int Datatype;
typedef struct Node{
Datatype data;
struct Node *next;
}Node,*Linklist;
单链表
头插建立
将新节点插入到当前链表的表头结点之后。形成 L→p4→p3→p2→p1这样的链式 (建立的次序和输入的节点次序相反)
int main(){
// 初始化空表
Linklist L=(Linklist)malloc(sizeof(Node));
L->next=NULL;
// 引入 p1指向的节点
Linklist p1=(Linklist)malloc(sizeof(Node));
p1->data=1;
// 将 p1指向的节点与 L指向的节点 相连
p1->next=L->next;
L->next=p1;
Linklist p2=(Linklist)malloc(sizeof(Node));
p2->data=2;
p2->next=L->next;
L->next=p2;
}
尾插建立
将新节点插入到当前链表的表尾上。 L→p1→p2→p3→p4 (建立的次序和输入的节点次序相同)
int main(){
Linklist L=(Linklist)malloc(sizeof(Node));
L->next=NULL;
Linklist R=L; // 建立尾指针,并始终指向链尾
Linklist p1=(Linklist)malloc(sizeof(Node));
p1->data=1;
p1->next=R->next;
R->next=p1;
R=p1; // 更新 R,指向链尾
Linklist p2=(Linklist)malloc(sizeof(Node));
p2->data=2;
p2->next=R->next;
R->next=p2;
R=p2;
}
连接了多少个节点?
// 获取 单链表 的长度 (连接了多少个节点)
int list_length (Linklist L){ // 传入 单链表的 表头指针 L
int count=0;
Linklist p=L->next;
while(p){
count++;
p=p->next;
}
return count;
}
单链表找到特定位置
// 找到值为 x 的节点
Linklist search_x(Linklist L,Datatype x){
Linklist p=L->next;
while(p){
if(p->data!=x){
p=p->next;
}else{
break; // 查找成功
}
}
if(p==NULL){ // 查找失败
printf("没有找到值为%d的节点!",x);
}
return p;
}
单链表的插入
单链表的删除
// 删除 L 中 p 指向的节点
void Dellist(Linklist L,Linklist p){
Linklist pre=L->next;
while(pre->next!=p){ // 找到 p 的前驱节点。
pre=pre->next;
}
pre->next=p->next;
free(p);
}
单链表逆置
将表头和其他节点断开前,都要记得预存后面的一个节点。
// 将单链表就地逆置
void rev(Linklist L){
Linklist p=L->next,q; // p先预存第一个节点的位置
L->next=NULL; // 将表头和其他节点断开
while(p){
q=p->next; // 记录 q 始终为 p的后一个节点 , 预存后边节点的位置
p->next=L->next;
L->next=p; // 通过p找到的节点作为新插入的节点 头插建立,插入到头节点之后
p=q; // 更新 p
}
}
单链表的合并
非递减有序排列:即递增,但不是严格单调递增。
两个单链表 LA 和 LB,其元素均为非递减有序排列。现将他们合并为 LC ,要求 LC 也是非递减有序排列。
// 将两个非递减有序排列单链表 LA 和 LB 合并为非递减有序排列 LC
Linklist merge(Linklist LA,Linklist LB){
Linklist pa,pb,LC,R;
pa=LA->next; // 预存后边节点的位置
pb=LB->next;
LC=LA; // 可以选择 LA 或 LB作为合并后单链表的表头指针 LC
LC->next=NULL; // 进行断开
R=LC; // 设置尾指针
// 循环比较找到值最小的节点进行尾插。
while(pa&&pb){
if(pa->data<=pb->data){
R->next=pa;
R=pa; // pa指向的节点中的数据更小时,将 pa 指向的节点进行插入 (尾插)。
pa=pa->next; // pa 向后移
}else{
R->next=pb;
R=pb; // pb指向的节点中的数据更小时,将 ....
pb=pb->next; // pb 向后移
}
}
// 循环结束后没有结束的表节点 直接串联到尾指针之后。
if(pa){
R->next=pa;
}else{ // 当 pa和pb二者有一个是 NULL时 直接将尾指针和后续节点连接
R->next=pb;
}
free(LB);
return LC;
}