• 数据结构基础--栈和队列


    一、栈

     栈:一种特殊的线性表,只允许在固定的一端进行插入与删除元素操作。
    进行数据插入和删除操作的一段,称为栈顶,另一端称为栈底
    栈中的数据元素遵循后进先出LIFO的原则
    压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
    出栈:栈的删除操作叫做出栈。出数据在栈顶

    如果用数组实现,相当于顺序表的尾插尾删,用尾去做了栈顶,唯一的缺陷就是空间不够需要增容
    如果用链表实现,如果用链表尾做栈顶,那么用双向链表更方便
    如果要用单链表实现,那么就用头去做栈顶更好,入栈出栈效率都是O(1)

     栈的接口函数:

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. typedef int STDataType;
    8. typedef struct Stack
    9. {
    10. STDataType* a;//建立一个动态数组
    11. STDataType top;//栈顶
    12. STDataType capacity;//栈的容量
    13. }ST;
    14. //接口函数
    15. void StackInit(ST* ps);//初始化
    16. void StackDestory(ST* ps);//销毁
    17. void StackPush(ST*ps,STDataType x);//入栈,不分头插尾插,因为栈只能在栈顶操作
    18. void StackPop(ST* ps);//出栈
    19. STDataType StackTop(ST* ps);//取栈顶数据
    20. int StackSize(ST* ps);//得到栈的数据个数
    21. bool StackEmpty(ST* ps);//判断栈是否为空

     栈接口函数的实现:

    1. #include"Stack.h"
    2. //栈:一种特殊的线性表,只允许在固定的一端进行插入与删除元素操作。
    3. //进行数据插入和删除操作的一段,称为栈顶,另一端称为栈底
    4. //栈中的数据元素遵循后进先出LIFO的原则
    5. //压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
    6. //出栈:栈的删除操作叫做出栈。出数据在栈顶
    7. //如果用数组实现,相当于顺序表的尾插尾删,用尾去做了栈顶,唯一的缺陷就是空间不够需要增容
    8. //如果用链表实现,如果用链表尾做栈顶,那么用双向链表更方便
    9. //如果要用单链表实现,那么就用头去做栈顶更好,入栈出栈效率都是O(1)
    10. void StackInit(ST* ps)
    11. {
    12. assert(ps);
    13. ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
    14. if (ps->a==NULL)
    15. {
    16. printf("malloc fail\n");
    17. exit(-1);
    18. }
    19. ps->capacity = 4;
    20. ps->top = 0;
    21. //初始top=0,意味着top指向栈顶元素的下一个
    22. //初始top=-1,意味着top指向栈顶元素
    23. }
    24. void StackDestory(ST* ps)
    25. {
    26. assert(ps);
    27. free(ps->a);
    28. ps->a = NULL;
    29. ps->top = ps->capacity = 0;
    30. }
    31. void StackPush(ST* ps,STDataType x)
    32. {
    33. assert(ps);
    34. if (ps->top==ps->capacity)
    35. {
    36. STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
    37. if (tmp==NULL)
    38. {
    39. printf("realloc fail\n");
    40. exit(-1);//终止程序
    41. }
    42. else
    43. {
    44. ps->a = tmp;
    45. ps->capacity *= 2;
    46. }
    47. }
    48. ps->a[ps->top] = x;
    49. ps->top++;
    50. }
    51. void StackPop(ST* ps)
    52. {
    53. assert(ps);
    54. assert(ps->top>0);//空栈时调用top直接终止程序报错
    55. ps->top--;//直接将栈顶数据删除,下一次有数据入栈会覆盖top位置
    56. }
    57. STDataType StackTop(ST* ps)//取栈顶元素
    58. {
    59. assert(ps);
    60. assert(ps->top>0);
    61. return ps->a[ps->top - 1];
    62. }
    63. int StackSize(ST* ps)
    64. {
    65. assert(ps);
    66. return ps->top;
    67. }
    68. bool StackEmpty(ST* ps)
    69. {
    70. assert(ps);
    71. return ps->top == 0;//如果top为零,说明栈中没有元素,为空
    72. //返回布尔值为1
    73. }

    二、队列

     队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表
    队列具有先进先出的特点
    入队列:进行插入操作的一段称为队尾
    出队列:进行删除操作的一段称为队头

    如果采用数组,队头出数据需要挪动数据
    如果采用单链表,入数据就是尾插,出数据就是头删

    队列的接口函数:

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. typedef int QDataType;
    7. typedef struct QueueNode//创建一个队列节点
    8. {
    9. struct QueueNode* next;
    10. QDataType data;
    11. }QNode;
    12. typedef struct Queue//创建一个队列
    13. {
    14. QNode* head;//指向队头
    15. QNode* tail;//指向队尾
    16. }Queue;
    17. void QueueInit(Queue* Q1);
    18. void QueueDestory(Queue* Q1);
    19. void QueuePush(Queue* Q1,QDataType x);//队尾入
    20. void QueuePop(Queue* Q1);//队头出
    21. QDataType QueueFront(Queue* Q1);
    22. QDataType QueueBack(Queue* Q1);
    23. int QueueSize(Queue* Q1);
    24. bool QueueEmpty(Queue* Q1);

    队列接口函数的实现: 

    1. //队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表
    2. //队列具有先进先出的特点
    3. //入队列:进行插入操作的一段称为队尾
    4. //出队列:进行删除操作的一段称为队头
    5. //如果采用数组,队头出数据需要挪动数据
    6. //如果采用单链表,入数据就是尾插,出数据就是头删
    7. #include"Queue.h"
    8. void QueueInit(Queue* Q1)
    9. {
    10. assert(Q1);
    11. Q1->head = Q1->tail = NULL;
    12. }
    13. void QueueDestory(Queue* Q1)
    14. {
    15. assert(Q1);
    16. QNode* cur = Q1->head;
    17. while (cur)
    18. {
    19. QNode * next = cur->next;
    20. free(cur);
    21. cur = next;
    22. }
    23. }
    24. void QueuePush(Queue* Q1,QDataType x)
    25. {
    26. assert(Q1);
    27. QNode* newnode = (QNode*)malloc(sizeof(QNode));
    28. if (newnode==NULL)
    29. {
    30. printf("malloc fail\n");
    31. exit(-1);
    32. }
    33. newnode->data = x;
    34. newnode->next = NULL;
    35. if (Q1->tail==NULL)
    36. {
    37. Q1->head =Q1->tail= newnode;
    38. }
    39. else
    40. {
    41. Q1->tail->next = newnode;//在tail后插入新结点
    42. Q1->tail = newnode;//将新结点变为为结点
    43. }
    44. }
    45. void QueuePop(Queue* Q1)
    46. {
    47. assert(Q1);
    48. assert(Q1->head);//保证队列存在,并且队列不为空
    49. if (Q1->head->next==NULL)
    50. {
    51. free(Q1->head);
    52. Q1->head = Q1->tail = NULL;//将队头队尾指针置空,避免野指针问题
    53. }
    54. else
    55. {
    56. QNode* next = Q1->head->next;
    57. free(Q1->head);
    58. Q1->head = next;
    59. }
    60. }
    61. QDataType QueueFront(Queue* Q1)
    62. {
    63. assert(Q1);
    64. assert(Q1->head);
    65. return Q1->head->data;
    66. }
    67. QDataType QueueBack(Queue* Q1)
    68. {
    69. assert(Q1);
    70. assert(Q1->tail);
    71. return Q1->tail->data;
    72. }
    73. int QueueSize(Queue* Q1)
    74. {
    75. assert(Q1);
    76. int size = 0;
    77. QNode* cur = Q1->head;
    78. while (cur)
    79. {
    80. ++size;
    81. cur = cur->next;
    82. }
    83. return size;
    84. }
    85. bool QueueEmpty(Queue* Q1)
    86. {
    87. assert(Q1);
    88. return Q1->head == NULL;
    89. }
  • 相关阅读:
    4年北漂之路,从软件测试外包到外企的一点小心得
    大模型能力
    make编译错误输出乱码的一种原因,与特殊符号的字符集相关
    2022数学建模国赛C题思路分析
    技术管理进阶——你了解成长的全貌吗?
    笔试强训Day2
    面向Java开发者的ChatGPT提示词工程(6)
    Day53【动态规划】1143.最长公共子序列、1035.不相交的线、53.最大子序和
    Java 线程的几种状态
    TCP的滑动窗口协议有什么用?
  • 原文地址:https://blog.csdn.net/RXY24601/article/details/127773680