前言

数据结构中顺序循环队列和链队列的C/C++语言描述实现模板,有详细的步骤解析及使用示例。


代码仓库


sqQueue.cpp(顺序循环队列)

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//头文件————————————————————
#include <iostream>

//命名空间————————————————————
using namespace std;

//宏————————————————————
#define MaxSize 100 //队列的最大大小

//自定义数据类型————————————————————
typedef int ElemType; //数据的(数据)类型 依据数据的实际类型定义

//结构体
//顺序循环队列
typedef struct SqQueue
{
ElemType data[MaxSize]; //数据
int front; //队头指针 定义为指向队头元素位置 出队:先出后移
int rear; //队尾指针 定义为指向队尾元素位置的下一个位置 入队:先入后移
} SqQueue;

//函数声明————————————————————
void use_example(); //使用示例
void init(SqQueue &sqQueue); //初始化
bool enQueue(SqQueue &sqQueue, ElemType elem); //入队
bool deQueue(SqQueue &sqQueue, ElemType &elem); //出队

//主函数————————————————————
int main()
{
use_example(); //使用示例

return 0;
}

//函数定义————————————————————
//使用示例
void use_example()
{
//创建
SqQueue sqQueue;

//初始化
init(sqQueue);
cout << sqQueue.front << endl; //输出:0
cout << sqQueue.rear << endl; //输出:0

//入队
ElemType elem1 = 100;
ElemType elem2 = 200;
ElemType elem3 = 300;

enQueue(sqQueue, elem1);
enQueue(sqQueue, elem2);
enQueue(sqQueue, elem3); //元素在栈中的排列:100,200,300

//出队
ElemType elem4 = 0;
ElemType elem5 = 0;

deQueue(sqQueue, elem4);
deQueue(sqQueue, elem5);

cout << elem4 << endl; //输出:100
cout << elem5 << endl; //输出:200

return;
}

//初始化
void init(SqQueue &sqQueue) //参数:队列
{
//定义队头指针和队尾指针指向索引/位置0为队空
sqQueue.front = 0;
sqQueue.rear = 0;
}

//入队
//时间复杂度:O(1)
bool enQueue(SqQueue &sqQueue, ElemType elem) //参数:队列,元素
{
if ((sqQueue.rear + 1) % MaxSize == sqQueue.front) //队满
{
return false;
}

sqQueue.data[sqQueue.rear] = elem; //元素入队
sqQueue.rear = (sqQueue.rear + 1) % MaxSize; //队尾指针循环+1

return true;
}

//出队
//时间复杂度:O(1)
bool deQueue(SqQueue &sqQueue, ElemType &elem) //参数:队列,元素
{
if (sqQueue.front == sqQueue.rear) //队空
{
return false;
}

elem = sqQueue.data[sqQueue.front]; //获取、保存元素
sqQueue.front = (sqQueue.front + 1) % MaxSize; //队头指针循环+1 元素出队

return true;
}

linkQueue.cpp(链队列)

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//头文件————————————————————
#include <iostream>

//命名空间————————————————————
using namespace std;

//自定义数据类型————————————————————
typedef int ElemType; //数据的(数据)类型 依据数据的实际类型定义

//结构体
//链队列结点
typedef struct LinkNode
{
ElemType data; //数据
struct LinkNode *next; //指针
} LinkNode;

//链队列
//因为需要保存两个结点指针,所以新定义结构体封装
typedef struct LinkQueue
{
LinkNode *front; //队头结点指针
LinkNode *rear; //队尾结点指针
} LinkQueue;

//函数声明————————————————————
void use_example(); //使用示例
void init(LinkQueue &linkQueue); //初始化
void enQueue(LinkQueue &linkQueue, ElemType elem); //入队
bool deQueue(LinkQueue &linkQueue, ElemType &elem); //出队

//主函数————————————————————
int main()
{
use_example(); //使用示例

return 0;
}

//函数定义————————————————————
//使用示例
void use_example()
{
//创建
LinkQueue linkQueue; //队列

//初始化
init(linkQueue);

//入队
ElemType elem1 = 100;
ElemType elem2 = 200;
ElemType elem3 = 300;

enQueue(linkQueue, elem1);
enQueue(linkQueue, elem2);
enQueue(linkQueue, elem3); //元素在栈中的排列:100,200,300

//出队
ElemType elem4 = 0;
ElemType elem5 = 0;

deQueue(linkQueue, elem4);
deQueue(linkQueue, elem5);

cout << elem4 << endl; //输出:100
cout << elem5 << endl; //输出:200

return;
}

//初始化
void init(LinkQueue &linkQueue) //参数:队列
{
linkQueue.front = linkQueue.rear = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点 队列的队头、尾结点指针指向头结点
linkQueue.front->next = nullptr; //头结点的指针指向空 即:linkQueue.rear->next = nullptr;
}

//入队
//时间复杂度:O(1)
void enQueue(LinkQueue &linkQueue, ElemType elem) //参数:队列,元素
{
LinkNode *newNode; //新结点指针

newNode = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点

newNode->data = elem; //初始化新结点的数据

//入队
linkQueue.rear->next = newNode;
linkQueue.rear = newNode;
}

//出栈
//时间复杂度:O(1)
bool deQueue(LinkQueue &linkQueue, ElemType &elem) //参数:队列,元素
{
if (linkQueue.front == linkQueue.rear) //队空
{
return false;
}

LinkNode *tempNode = nullptr; //临时结点指针

elem = linkQueue.front->next->data; //获取、保存数据

//出队
tempNode = linkQueue.front->next;
linkQueue.front->next = tempNode->next;

//易漏边界条件:如果除头结点只剩一个元素,该元素出队后,将队尾结点指针指向队头指针指向的头结点
if (linkQueue.rear == tempNode)
{
linkQueue.rear = linkQueue.front;
}

free(tempNode); //释放结点空间

return true;
}

总结

不同参考资料中,顺序循环队列和链队列的描述实现各不相同,但基本思想是一致的。作者使用规范的变量命名、提供详细的步骤解析及使用示例,应用C/C++语言将其整合成模板,以帮助理解记忆。


参考资料

  • 《2023版数据结构高分笔记》主编:率辉
  • 《2023年计算机组成原理考研复习指导》组编:王道论坛
  • 《大话数据结构》作者:程杰

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获