数据结构之线性表-循环链表-学习笔记-22

引入

我们讲了顺序存储结构、单链表、静态链表,今天我们学习一种新的链表,单循环链表,单循环链表很简单,其实就是在单链表的基础上,将头尾相连,形成一个单向环装循环。

单循环链表

我们知道,单链表非常有趣,虽然不连续,但却根据指针一个连着一个,但是单链表有一个问题,我们如果不从头结点出发,就无法访问所有结点。
解决方法也非常简单,就是把链表终端结点得指针由 NULL 改成指向头结点。也就是链表最后一个结点存储得指针为头结点得指针,也就是原来 head 存储的地址。
既然head 和 最后一个结点 都指向头结点,那么我们就称这种头尾相接得单链表位单循环链表

单循环链表的特点

既然头尾相接,那么单循环链表有新增了下面几种特性

  • head 指向头结点,尾部也指向头结点
  • 判断空表得时候,只要头结点和头部指向得内容都是该结点本身,那么这个表就是空表。
  • 头结点即尾部,头结点指向头结点,head 指向头结点
  • 原来是 head->next 是否为 NULL,是就为空表
  • 现在是 head 是否等于 head->next,即头结点指针指向它自己
  • 我们把最后一个结点得指针称为 rear

单循环链表

我们先生成一个5结点的链表,然后向后插入一位,看看,还是不是单向循环链表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LEN sizeof(struct Student)
#define MAXSIZE 5

struct Student{
int num;
float score;
struct Student *next;
};


struct Student *stu_init(){
srand((time(0)));
struct Student *a,*b,*head;
a=b=(struct Student *)malloc(LEN);
int n=0;
while(n<=MAXSIZE){
a=(struct Student *)malloc(LEN);
a->num=n;
a->score=rand()%100+1;
if(n==1){
head=a;
b=a;
}else{
b->next=a;
b=a;
}
n=n+1;
}
b->next=head;
return head;
}

void stu_printf(struct Student *stu_p){
struct Student *stu,*head;
stu=head=stu_p;
while(stu->next!=head){
printf("%d号%3.1f分\n",stu->num,stu->score);
stu=stu->next;
}
}

void stu_insert(struct Student *stu_p , int num , float data){
struct Student *target , *temp;
target=stu_p;
if(num==1){
target->num=num;
target->score=data;
target->next=stu_p;
}else{
for(int l=0;l<num-1;l++){
target=target->next;
}
temp=(struct Student *)malloc(LEN);
temp->score=data;
temp->num=num;
temp->next=target->next;
target->next=temp;
}
printf("%d\n",temp->next->num);

}

int main(){
struct Student *stu;
stu=stu_init();
stu_insert(stu, 5, 11.1);
stu_printf(stu);
}

输出
1
1号65.0分
2号25.0分
3号66.0分
4号12.0分
5号47.0分

初始化:初始化完成后,一定要记得把首尾相连,否则构不成循环。

插入:插入的时候一定要记得沿着链表来找,找到前一个,然后将其指针域赋值给插入得结点,然后将指针域指向插入的结点的地址。

判断:上面的1输出得是printf("%d\n",temp->next->num); 也就是最后插入的这个结点的下一结点得编号,如果是循环链表的话,那么就应该是1才对,因为又会指向头结点。

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!