当前位置:   article > 正文

数据结构--栈和队列 源码

数据结构--栈和队列 源码

一,栈

栈类似于弹匣,先进后出

实现方法:动态顺序表


Stack.h 文件:
源码:

  1. #pragma once
  2. #include<stdlib.h>
  3. #include<iostream>
  4. using namespace std;
  5. typedef int type;
  6. struct Stack
  7. {
  8. type* arr;
  9. int top;
  10. int capacity;
  11. };
  12. typedef struct Stack ST;
  13. // 初始化栈
  14. void StackInit(ST* ps);
  15. // 入栈
  16. void StackPush(ST* ps, type data);
  17. // 出栈
  18. void StackPop(ST* ps);
  19. // 获取栈顶元素
  20. type StackTop(ST* ps);
  21. // 获取栈中有效元素个数
  22. int StackSize(ST* ps);
  23. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  24. int StackEmpty(ST* ps);
  25. // 销毁栈
  26. void StackDestroy(ST* ps);
  27. void menu();


实现文件

St.cpp

源码:

  1. #include"Stack.h"
  2. void StackInit(ST* ps)
  3. {
  4. ps->capacity = 0;
  5. ps->arr = NULL;
  6. ps->top = 0;
  7. }
  8. void StackPush(ST* ps, type data)
  9. {
  10. int newcap = 0;
  11. if (ps->top+1>= ps->capacity)
  12. {
  13. newcap = ps->capacity == 0 ? 4 : ps->capacity * 2;
  14. type* neww = (type*)realloc(ps->arr,newcap * sizeof type);
  15. if (neww == NULL)
  16. {
  17. printf("malloc is fail\n");
  18. return;
  19. }
  20. ps->arr = neww;
  21. ps->capacity = newcap;
  22. }
  23. ps->arr[++ps->top] = data;
  24. }
  25. void StackPop(ST* ps)
  26. {
  27. if (ps->top <= 0)
  28. {
  29. printf("stack is empty\n");
  30. return;
  31. }
  32. ps->top--;
  33. }
  34. type StackTop(ST* ps)
  35. {
  36. if (ps->top <= 0)
  37. {
  38. printf("stack is empty\n");
  39. return -1;
  40. }
  41. return ps->arr[ps->top];
  42. }
  43. int StackSize(ST* ps)
  44. {
  45. return ps->top;
  46. }
  47. int StackEmpty(ST* ps)
  48. {
  49. if (ps->top <= 0)
  50. {
  51. return 1;
  52. }
  53. else
  54. {
  55. return 0;
  56. }
  57. }
  58. void StackDestroy(ST* ps)
  59. {
  60. if (ps == NULL)
  61. {
  62. return;
  63. }
  64. free(ps->arr);
  65. ps->capacity = 0;
  66. ps->top = 0;
  67. }
  68. void menu()
  69. {
  70. printf("**********************\n");
  71. printf("***1.StackPush********\n");
  72. printf("***2.StackPop*********\n");
  73. printf("***3.StackTop*********\n");
  74. printf("***4.StackSize********\n");
  75. printf("***5.StackEmpty*******\n");
  76. printf("***6.StackDestroy*****\n");
  77. printf("**********************\n");
  78. }

1.1 StackInit 初始化函数

  1. void StackInit(ST* ps)
  2. {
  3. ps->capacity = 0;
  4. ps->arr = NULL;
  5. ps->top = 0;
  6. }

(1).把动态顺序表初始化为NULL,把top和capacity 初始化为0。

1.2 StackPush 插入函数

  1. void StackPush(ST* ps, type data)
  2. {
  3. int newcap = 0;
  4. if (ps->top+1>= ps->capacity)
  5. {
  6. newcap = ps->capacity == 0 ? 4 : ps->capacity * 2;
  7. type* neww = (type*)realloc(ps->arr,newcap * sizeof type);
  8. if (neww == NULL)
  9. {
  10. printf("malloc is fail\n");
  11. return;
  12. }
  13. ps->arr = neww;
  14. ps->capacity = newcap;
  15. }
  16. ps->arr[++ps->top] = data;
  17. }

(1).首先检查动态顺序表容量是否装满。装满后使用realloc函数扩容。

(2).检查完毕后,要先加加再赋值,因为要以top==0为栈空条件,所以top等于0的地方不能存值。

1.3 StackPop 出栈函数

  1. void StackPop(ST* ps)
  2. {
  3. if (ps->top <= 0)
  4. {
  5. printf("stack is empty\n");
  6. return;
  7. }
  8. ps->top--;
  9. }

(1).先判断栈是否为空,为空就输出提出并返回。

(2).只需直接将top减1即可,不需要将top的地方赋值为0再减1。

1.4 StackTop 输出栈顶

  1. type StackTop(ST* ps)
  2. {
  3. if (ps->top <= 0)
  4. {
  5. printf("stack is empty\n");
  6. return -1;
  7. }
  8. return ps->arr[ps->top];
  9. }

(1).先检查栈是否为空,为空则输出提示并返回。

(2).不为空则直接返回位于top的数值。

1.5 StackSize 返回栈元素个数

  1. int StackSize(ST* ps)
  2. {
  3. return ps->top;
  4. }

(1).由于是先加加top,所以top的值即为栈元素个数。

1.6 StackEmpty 判断栈是否为空

  1. int StackEmpty(ST* ps)
  2. {
  3. if (ps->top <= 0)
  4. {
  5. return 1;
  6. }
  7. else
  8. {
  9. return 0;
  10. }
  11. }

(1).根据top来判断,如果top为0,则返回真,否则返回假。

1.7 StackDestroy 销毁栈

  1. void StackDestroy(ST* ps)
  2. {
  3. if (ps == NULL)
  4. {
  5. return;
  6. }
  7. free(ps->arr);
  8. ps->capacity = 0;
  9. ps->top = 0;
  10. }

(1).直接将arr销毁即可,使用free函数,并将top和capacity都置为0。


二,队列

实现方法:单链表

使用两个结构体来操作


Queue.h 文件

  1. #pragma once
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. typedef int type;
  5. struct node
  6. {
  7. struct node* next;
  8. type val;
  9. };
  10. struct Queue
  11. {
  12. node* head;
  13. node* tail;
  14. int size;
  15. };
  16. typedef struct node node;
  17. typedef struct Queue Queue;
  18. // 初始化队列
  19. void QueueInit(Queue* q);
  20. // 队尾入队列
  21. void QueuePush(Queue* q, type data);
  22. // 队头出队列
  23. void QueuePop(Queue* q);
  24. // 获取队列头部元素
  25. type QueueFront(Queue* q);
  26. // 获取队列队尾元素
  27. type QueueBack(Queue* q);
  28. // 获取队列中有效元素个数
  29. int QueueSize(Queue* q);
  30. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  31. int QueueEmpty(Queue* q);
  32. // 销毁队列
  33. void QueueDestroy(Queue* q);
  34. void menu();

(1).使用两个结构体,node为结点结构体,Queue为队列结构体用于存放头结点和尾结点。


Q.cpp 文件

源码:

  1. #include"Queue.h"
  2. // 初始化队列
  3. void QueueInit(Queue* q)
  4. {
  5. q->head = NULL;
  6. q->tail = NULL;
  7. q->size = 0;
  8. }
  9. // 队尾入队列
  10. void QueuePush(Queue* q, type data)
  11. {
  12. node* neww = (node*)malloc(sizeof(node));
  13. neww->next = NULL;
  14. neww->val =data;
  15. if (q->head == NULL)
  16. {
  17. q->head = q->tail = neww;
  18. }
  19. else
  20. {
  21. q->tail->next = neww;
  22. q->tail = neww;
  23. }
  24. q->size++;
  25. }
  26. // 队头出队列
  27. void QueuePop(Queue* q)
  28. {
  29. if (q->head != NULL)
  30. {
  31. node* temp = q->head->next;
  32. free(q->head);
  33. q->head = temp;
  34. q->size--;
  35. }
  36. }
  37. // 获取队列头部元素
  38. type QueueFront(Queue* q)
  39. {
  40. if (q->head != NULL)
  41. {
  42. return q->head->val;
  43. }
  44. cout << "queue is empty" << endl;
  45. return -1;
  46. }
  47. // 获取队列队尾元素
  48. type QueueBack(Queue* q)
  49. {
  50. if (q->head != NULL)
  51. {
  52. return q->tail->val;
  53. }
  54. cout << "queue is empty" << endl;
  55. return -1;
  56. }
  57. // 获取队列中有效元素个数
  58. int QueueSize(Queue* q)
  59. {
  60. return q->size;
  61. }
  62. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  63. int QueueEmpty(Queue* q)
  64. {
  65. return q->size == 0;
  66. }
  67. // 销毁队列
  68. void QueueDestroy(Queue* q)
  69. {
  70. node* cur = q->head;
  71. while (cur)
  72. {
  73. node* temp = cur->next;
  74. free(cur);
  75. cur = temp;
  76. }
  77. cur = NULL;
  78. }
  79. void menu()
  80. {
  81. printf("********************\n");
  82. printf("***1.QueueInit******\n");
  83. printf("***2.QueuePush******\n");
  84. printf("***3.QueuePop*******\n");
  85. printf("***4.QueueFront*****\n");
  86. printf("***5.QueueBack******\n");
  87. printf("***6.QueueSize******\n");
  88. printf("***7.QueueEmpty*****\n");
  89. printf("***8.QueueDestroy***\n");
  90. printf("********************\n");
  91. }

2.1 QueueInit 初始化函数

  1. void QueueInit(Queue* q)
  2. {
  3. q->head = NULL;
  4. q->tail = NULL;
  5. q->size = 0;
  6. }

2.2 QueuePush 插入函数

  1. void QueuePush(Queue* q, type data)
  2. {
  3. node* neww = (node*)malloc(sizeof(node));
  4. neww->next = NULL;
  5. neww->val =data;
  6. if (q->head == NULL)
  7. {
  8. q->head = q->tail = neww;
  9. }
  10. else
  11. {
  12. q->tail->next = neww;
  13. q->tail = neww;
  14. }
  15. q->size++;
  16. }

(1).创建新结点,将新结点的next赋为NULL,并且把要插入的值赋值给新创建节点的val中。

(2).如果是最开始,也就是队列为空时,就要把头结点和尾结点都赋值为新创建的结点。

(3).如果不是最开始,就像单链表尾插一样。

(4).最后把size加一,方便要输出队列元素个数时,无需再O(n)遍历队列。

2.3 QueuePop 出队

  1. void QueuePop(Queue* q)
  2. {
  3. if (q->head != NULL)
  4. {
  5. node* temp = q->head->next;
  6. free(q->head);
  7. q->head = temp;
  8. q->size--;
  9. }
  10. }

(1),如果队列不为空,则按单链表中头删方法,删除队头。

2.4 QueueFront 获取队头元素值

  1. type QueueFront(Queue* q)
  2. {
  3. if (q->head != NULL)
  4. {
  5. return q->head->val;
  6. }
  7. cout << "queue is empty" << endl;
  8. return -1;
  9. }

(1).直接返回头结点的val值即可。

2.5 QueueBack 获取队尾元素值

  1. type QueueBack(Queue* q)
  2. {
  3. if (q->head != NULL)
  4. {
  5. return q->tail->val;
  6. }
  7. cout << "queue is empty" << endl;
  8. return -1;
  9. }

(1).直接返回尾结点的val值即可。

2.6 QueueSize 返回元素个数

  1. int QueueSize(Queue* q)
  2. {
  3. return q->size;
  4. }

(1).由于之前对size值的维护,所以直接返回size值即可。

2.7 QueueEmpty 判断队列是否为空

  1. int QueueEmpty(Queue* q)
  2. {
  3. return q->size == 0;
  4. }

(1).如果size为0,则队列为空。否则不为空。

2.8 QueueDestroy 销毁队列

  1. void QueueDestroy(Queue* q)
  2. {
  3. node* cur = q->head;
  4. while (cur)
  5. {
  6. node* temp = cur->next;
  7. free(cur);
  8. cur = temp;
  9. }
  10. cur = NULL;
  11. q->head = NULL;
  12. q->tail = NULL;
  13. q->size = 0;
  14. }

(1).遍历单链表,依次释放结点即可,最后把指针全部赋值为NULL。

完结

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/593707
推荐阅读
相关标签
  

闽ICP备14008679号