数据结构之线性表-单向循环链表的尾指针(上)-学习笔记-24

引入

我们学习了循环链表的基本操作,也学习了一个有趣的约瑟夫问题,我们之前说过有头指针也有尾指针,头指针指向头结点,尾指针指向尾结点。那么尾指针有哪些有趣的用法呢?

单循环链表的问题

我们知道,在单向循环链表中,我们有头指针

  • O ( 1 ) 的时间去找到第一个结点,因为 next 就是头结点
  • O ( n ) 的时间去找最后一个结点,因为第 n 个才是尾结点

如何在访问头结点和尾结点得时候,都是O( 1 )时间复杂度呢?

尾指针应运而生!

  • 尾指针指向的是尾节点
  • 而尾节点得下一个就是头结点

所以尾指针访问头结点和尾节点的时间都是 O ( 1 ) 。
撒花~~~

尾指针

我们看到这张图

  • 尾指针的名称为 rear
  • rear 指向得是终端结点的地址
  • rear 的 next 元素为头结点
  • 特点:特点就是可以灵活的操作头结点和尾结点

一个例题

创建两个单循环链表,将其合并成一个循环链表。

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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LEN sizeof(struct Student)
#define NUM 20
struct Student{
int num;
struct Student *next;
};

struct Student *create(int min,int max){
if(min>=max){
printf("输入错误!");
return 1;
}
struct Student *a,*b,*head;
int i=min;
while(min<=max){
a=(struct Student *)malloc(LEN);
if(min==i){
head=a;
}else{
b->next=a;
}
a->num=min++;
b=a;
}
b->next=head;
head=b;
return head;
}


void stu_print(struct Student *stu_p){
struct Student *head;
head=stu_p;
do{
printf("%d\n",stu_p->next->num);
}while((stu_p=stu_p->next)!=head);
}

struct Student *stu_mix(struct Student *stu_a,struct Student *stu_b){
struct Student *mix_a;
mix_a=stu_a->next; //保存 a 的头结点位置
stu_a->next=stu_b->next->next; // A的表尾存储得地址 改为 B头结点存储的位置,A的尾巴连接到B的头。A指向得是头结点指向的
stu_b->next=mix_a; // B的表尾存储的地址 改为 A 头结点得地址
return stu_b;
}


int main(){
struct Student *stu_a,*stu_b;
stu_a=create(1,20);
stu_b=create(21,40);
stu_print(stu_mix(stu_a,stu_b));
return 0;
}

合并两个单循环链表有三个步骤

  • 先把 A 的头结点的位置存下来
  • A 的尾巴指向 B 的头结点
  • B 得尾巴指向刚才存下在的 A 的头结点

尾巴

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


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