姓名:Far_Rainbow
    学号: 202505000X
    专业: 软件工程
    年级:2020级

    实验名称:实验5 链队列的基本操作

    实验内容

    (1)实验目的
    通过该实验,使学生理解链队列的构造特点并灵活应用,掌握链队基本操作的编程实现,认识栈是在一端进行插入,在另一端进行删除集中操作的线性结构,掌握队列的“先入先出”操作特点,知道判断队列空和满的条件,进一步熟悉C++中指针操作。

    (2)实验内容
    用链式存储结构,实现教材定义的队列的基本操作。

    (3)参考界面
    菜单中包括以下功能:

    1. 初始化队列
    2. 销毁队列
    3. 清空队列
    4. 队列判空
    5. 求队列长度
    6. 获取队头元素
    7. 插入一个 元素
    8. 删除一个元素
    9. 输出所有元素

    要求:自定义的函数中不允许出现提示语和输出语句。

    (4)验收/测试用例
    通过菜单调用各个操作,测试点:

    • 没有初始化前进行其他操作,程序是否能控制住;
    • 初始化一个队列;
    • 判队列空,屏幕显示队列为空;
    • 3个数入队, 3、5、7;
    • 队列长度,屏幕输出3;
    • 取队头元素,再判队列是否空,然后再判队列长度,(让学生知道取队头元素不改变队列中的内容,队头指针不发生改变);
    • 出队,再判队列长度和显示队列中剩余的元素;(多次出队,队列为空之后再执行出队操作,是否提示队列为空);
    • 入队一个元素2,再出队,再判断队列是否为空,(主要测试出队操作中特殊情况下的那两行代码是否写了);
    • 销毁队列,再做其他操作,判断程序是否能控制。

    实验类型:验证性

    实验的重难点:入栈和出栈、进制转换(十六进制)

    实验环境:TDM-GCC 4.9.2 64-bit

    实验步骤及完成任务情况
    一、设计思想

    1. 采用模板实现泛型编程,可创建任意数据类型的队列;
    2. 以双链表为原型实现链队列,双链表的header哨兵和trailer哨兵作为队列的队首指针front和队尾指针rear;
    3. 入队始终是将元素插入到队尾哨兵前,出队始终是删除队首哨兵后的元素,以保证队列被限制为只能从队尾入队,从队首出队;

    二、主要源代码

    1. #include <iostream>
    2. using std::cin;
    3. using std::cout;
    4. using std::endl;
    5. template <typename T> struct Qnode {
    6. T data;
    7. Qnode<T>* pred;
    8. Qnode<T>* succ;
    9. };
    10. template <typename T> class Queue {
    11. private:
    12. int _length;
    13. Qnode<T>* front;
    14. Qnode<T>* rear;
    15. public:
    16. void init();
    17. void destroy();
    18. void clear();
    19. Queue() : front(NULL), rear(NULL) { }
    20. ~Queue() {destroy(); }
    21. bool isempty() const {return _length > 0 ? 0 : 1; }
    22. int getlength() const {return _length; }
    23. bool exist() const {return front != NULL ? 1 : 0;}
    24. T& getfront() const {return front->succ->data; }
    25. T& getrear() const {return rear->pred->data; }
    26. void enqueue(T const& e);
    27. T dequeue();
    28. void traverse();
    29. };
    30. template <typename T> void Queue<T>::init()
    31. {
    32. front = new Qnode<T>;
    33. rear = new Qnode<T>;
    34. front->succ = rear;
    35. front->pred = NULL;
    36. rear->pred = front;
    37. rear->succ = NULL;
    38. _length = 0;
    39. }
    40. template <typename T> void Queue<T>::destroy()
    41. {
    42. Qnode<T>* p = front, *q;
    43. while(p){
    44. q = p->succ;
    45. delete p;
    46. p = q;
    47. }
    48. front = NULL;
    49. rear = NULL;
    50. _length = 0;
    51. }
    52. template <typename T> void Queue<T>::clear()
    53. {
    54. Qnode<T>* p = front->succ, *q;
    55. while(p != rear){
    56. q = p->succ;
    57. delete p;
    58. p = q;
    59. }
    60. front->succ = rear;
    61. rear->pred = front;
    62. _length = 0;
    63. }
    64. template <typename T> void Queue<T>::enqueue(T const& e)
    65. {
    66. Qnode<T>* p = new Qnode<T>;
    67. p->data = e;
    68. p->pred = rear->pred;
    69. p->succ = rear;
    70. rear->pred->succ = p;
    71. rear->pred = p;
    72. ++ _length;
    73. }
    74. template <typename T> T Queue<T>::dequeue()
    75. {
    76. Qnode<T>* p = front->succ;
    77. front->succ = p->succ;
    78. p->succ->pred = front;
    79. T e = p->data;
    80. delete p;
    81. -- _length;
    82. return e;
    83. }
    84. template <typename T> void Queue<T>::traverse()
    85. {
    86. Qnode<T>* p = front->succ;
    87. while(p != rear) {
    88. cout<<p->data<<' ';
    89. p = p->succ;
    90. }
    91. }
    92. int main()
    93. {
    94. cout<<"\n 链队列的基本操作\n\n";
    95. cout<<"1---初始化队列\n";
    96. cout<<"2---销毁队列\n";
    97. cout<<"3---清空队列\n";
    98. cout<<"4---队列判空\n";
    99. cout<<"5---求队列长度\n";
    100. cout<<"6---获取队头元素\n";
    101. cout<<"7---插入一个元素\n";
    102. cout<<"8---删除一个元素\n";
    103. cout<<"9---输出所有元素\n";
    104. cout<<"\n\t退出,输入一个负数!\n\n";
    105. Queue<int> q;
    106. int e;
    107. while(true){
    108. int myOption;
    109. cout<<"\n请输入操作序号:";
    110. cin>>myOption;
    111. switch(myOption){
    112. case 1:{
    113. if(q.exist()){
    114. cout<<"初始化失败,队列已存在\n";
    115. break;
    116. }
    117. q.init();
    118. cout<<"初始化成功!\n";
    119. break;
    120. }
    121. case 2:{
    122. if (!q.exist()){
    123. cout<<"销毁失败,队列不存在\n";
    124. break;
    125. }
    126. q.destroy();
    127. cout<<"销毁成功!\n";
    128. break;
    129. }
    130. case 3:{
    131. if (!q.exist()){
    132. cout<<"清空失败,队列不存在\n";
    133. break;
    134. }
    135. if (q.isempty()) ;
    136. else q.clear();
    137. cout<<"清空成功!\n";
    138. break;
    139. }
    140. case 4:{
    141. if (!q.exist()){
    142. cout<<"判空失败,队列不存在\n";
    143. break;
    144. }
    145. if (q.isempty()) cout<<"队列为空!\n";
    146. else cout<<"队列非空!\n";
    147. break;
    148. }
    149. case 5:{
    150. if (!q.exist()){
    151. cout<<"请先创建队列!\n";
    152. break;
    153. }
    154. cout<<"队列的长度是"<<q.getlength()<<endl;
    155. break;
    156. }
    157. case 6:{
    158. if (!q.exist()){
    159. cout<<"获取失败,队列不存在\n";
    160. break;
    161. }
    162. if (q.isempty()){
    163. cout<<"队列为空,无队首元素!\n";
    164. break;
    165. }
    166. cout<<"队首元素是"<<q.getfront()<<endl;
    167. break;
    168. }
    169. case 7:{
    170. if (!q.exist()){
    171. cout<<"插入失败,队列不存在!\n";
    172. break;
    173. }
    174. cout<<"请输入待插入元素e\n"<<" e为:";
    175. cin>>e;
    176. q.enqueue(e);
    177. break;
    178. }
    179. case 8:{
    180. if (!q.exist()){
    181. cout<<"删除失败,队列不存在!\n";
    182. break;
    183. }
    184. if (q.isempty()){
    185. cout<<"队列为空,删除失败!\n";
    186. break;
    187. }
    188. else {
    189. e = q.dequeue();
    190. cout<<"被删除的元素是:"<<e<<endl;
    191. }
    192. break;
    193. }
    194. case 9:{
    195. if (!q.exist()){
    196. cout<<"遍历并输出失败,队列不存在!\n";
    197. break;
    198. }
    199. if (q.isempty()){
    200. cout<<"队列为空!\n";
    201. break;
    202. }
    203. cout<<"队列的所有元素是:";
    204. q.traverse();
    205. cout<<endl;
    206. break;
    207. }
    208. }
    209. if(myOption > 9 || myOption == 0) cout<<"\n请输入小于9的正整数\n\n";
    210. if(myOption < 0){
    211. cout<<"\n退出程序!\n";
    212. break;
    213. }
    214. }
    215. return 0;
    216. }

    实验结果
    实验5 链队列的基本操作 - 图1
    实验5 链队列的基本操作 - 图2
    实验5 链队列的基本操作 - 图3
    实验5 链队列的基本操作 - 图4
    实验5 链队列的基本操作 - 图5