1.结构上(图形):单链表最后一个节点指向NULL,循环单链表最后一个节点指向头节点L,反正就是尾节点不同,一个是NULL,一个是L。
2.结构体定义上:单链表和循环单链表结构体定义一样
typedef struct Node{
ElemType data;//数据域
struct Node *next;//指针域
}NODE,*Linklist;
3.初始化:
(1)单链表初始化:末节点=NULL(L->next=NULL;)
void Initlist(){
//定义头节点L
LNODE *L=(LNODE*)malloc(sizeof(LNODE));
L->data=0;//头节点的data用来存储表长
L->next=NULL;//头节点的next用来指向链表的第一个节点
return L;
}
//主函数
int main(){
Linklist L;
L=Initlist();
printf("%d",L->data);//test:如果初始化成功输出0
return 0;
}
(2)循环单链表:末节点=头节点(L->next=L;)
void Initlist(){
//定义头节点L
LNODE *L=(LNODE*)malloc(sizeof(LNODE));
L->data=0;//头节点的data用来存储表长
L->next=L;//区别!!!!!!
return L;
}
//主函数
int main(){
Linklist L;
L=Initlist();
printf("%d",L->data);//test:如果初始化成功输出0
return 0;
}
4.打印
(1)单链表:循环条件是p->next!=NULL
bool printLinklist(Linklist L){
LNode *p;//或者Linklist p,我前面结构体重命名过这个节点指针了
p=L;//p指向头节点L
//循环条件是p->next!=NULL
while(p->next){
p=p->next;//没到末节点就一直往下
printf("->%d",p->data);
}
return true;//bool类型或者void都行
}
(2)循环单链表:循环条件是p->next!=L
//循环条件是p->next!=L
void printlist(Linklist L){
Linklist p;
p=L;//让这个指针等于头指针
//区别!!!!!!
while(p->next!=L){
printf("->%d",p->data);
p=p->next;
}
printf("->NULL");
}
5.插入:以下代码均是带头节点的,头节点为L,
头插法和尾插法是两种常用的链表插入方式。
头插法是将新节点插入到链表的首部,注意这里是带头节点的单链表,首部是第二个节点,也就是让新节点成为链表的新的首节点,原来的首节点成为第二个节点(包括头节点,首节点就变成第三个节点),这种插入方式的时间复杂度为O(1),因为只需要修改指针,不需要遍历整个链表。
尾插法是将新节点插入到链表的尾部,也就是链表的最后一个节点的后面。这种插入方式需要遍历整个链表找到最后一个节点,再将新节点插入到其后面,时间复杂度为O(n)。
尾插法可以方便地实现链表的逆序,即将链表原来的顺序颠倒过来。
(1)头插与尾插
1.头插:要区分首节点和头节点L,头插法单链表和循环单链表都是一样的。
1)头插法创建链表(循环单和普通的单链表的头插法都是一样的,因为不涉及尾节点):
【1】原理图解:
【2】代码实现
bool head_insertlist(Linklist L){
Linklist s=(Linklist)malloc(sizeof(NODE));//设置一个指针s,并给它分配存储空间
ElemType e;//int变量e用于输入数据
scanf("%d",&e);//输入节点数据
//这里设置输入负数停止
while(e>0){
s->data=e;//把输入的数据存s里面
s->next=L->next;//上面图中的步骤1
L->nent=s;//步骤2
L->data++;//data是计数用的,这行头插尾插都要写
scanf("%d",&e);//data+一次1存一个键盘输入的数据e
}
return true;
}
2.尾插:先找到尾节点然后把该节点插入就行了,难点是寻找尾节点。
1)单链表尾插
【1】原理图解
【2】代码实现
void tailist(Linklist L){
Linklist s,r;
ElemType e;
r=L;
scanf("%d",&e);
while(e>0){
s=(Linklist)malloc(sizeof(NODE));
s->data=e;
r->next=s;
r=s;
scanf("%d",&e);
}
r->next=NULL;
return L;
}
2)循环单链表尾插:同上,循环条件改L就行了。