• 数据结构——栈与队列


    一、栈

    1.1   栈的概念及结构

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

    1.2 栈的实现(数组栈)

    栈的实现一般可以使用 数组或者链表实现 ,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

    1.2.1 栈的基本功能实现

    1. #include
    2. #include
    3. #include
    4. typedef int SDateType;
    5. typedef struct Stack
    6. {
    7. SDateType* a;
    8. int top;
    9. int capacity;
    10. }Stack;
    11. //初始化栈和销毁栈
    12. void InitStack(Stack* ps);
    13. void DestoryStack(Stack* ps);
    14. //出栈和入栈
    15. void StackPush(Stack* ps, SDateType x);
    16. void StackPop(Stack* ps);
    17. //栈的有效个数和栈顶元素
    18. int StackSize(Stack* ps);
    19. int StackTop(Stack* ps);
    20. //栈是否为空
    21. bool StackEmpty(Stack* ps);
    1.2.1.1 栈的初始化和销毁
    1. //初始化栈和销毁栈
    2. void InitStack(Stack* ps)
    3. {
    4. assert(ps);
    5. ps->a = NULL;
    6. ps->capacity = ps->top = 0;
    7. }
    8. void DestoryStack(Stack* ps)
    9. {
    10. assert(ps);
    11. free(ps->a);
    12. ps->a = NULL;
    13. ps->capacity = ps->top = 0;
    14. }
    1.2.1.2  入栈和出栈
    1. //出栈和入栈
    2. void StackPush(Stack* ps, SDateType x)
    3. {
    4. assert(ps);
    5. //扩容
    6. if (ps->top == ps->capacity)
    7. {
    8. SDateType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    9. SDateType* tmp = (SDateType*)realloc(ps->a,newcapacity*sizeof(SDateType));
    10. if (tmp == NULL)
    11. {
    12. perror("realloc fail:");
    13. return;
    14. }
    15. ps->a = tmp;
    16. ps->capacity = newcapacity;
    17. }
    18. //尾插
    19. ps->a[ps->top] = x;
    20. ps->top++;
    21. }
    22. void StackPop(Stack* ps)
    23. {
    24. assert(ps);
    25. assert(ps->top > 0);//只少有一个元素,才能删除
    26. ps->top--;
    27. }
    1.2.1.3 栈的元素个数和栈顶元素
    1. //栈的有效个数和栈顶元素
    2. int StackSize(Stack* ps)
    3. {
    4. assert(ps);
    5. return ps->top;
    6. }
    7. int StackTop(Stack* ps)
    8. {
    9. assert(ps);
    10. assert(ps->top > 0);
    11. return ps->a[ps->top - 1];
    12. }
    1.2.1.4  栈是否为空
    1. //栈是否为空
    2. bool StackEmpty(Stack* ps)
    3. {
    4. assert(ps);
    5. return ps->top == 0;
    6. }

    1.2.2  Stack.h

    1. #include
    2. #include
    3. #include
    4. typedef int SDateType;
    5. typedef struct Stack
    6. {
    7. SDateType* a;
    8. int top;
    9. int capacity;
    10. }Stack;
    11. //初始化栈和销毁栈
    12. void InitStack(Stack* ps);
    13. void DestoryStack(Stack* ps);
    14. //出栈和入栈
    15. void StackPush(Stack* ps, SDateType x);
    16. void StackPop(Stack* ps);
    17. //栈的有效个数和栈顶元素
    18. int StackSize(Stack* ps);
    19. int StackTop(Stack* ps);
    20. //栈是否为空
    21. bool StackEmpty(Stack* ps);

    1.2.3  Stach.c

    1. #include"Stack.h"
    2. //初始化栈和销毁栈
    3. void InitStack(Stack* ps)
    4. {
    5. assert(ps);
    6. ps->a = NULL;
    7. ps->capacity = ps->top = 0;
    8. }
    9. void DestoryStack(Stack* ps)
    10. {
    11. assert(ps);
    12. free(ps->a);
    13. ps->a = NULL;
    14. ps->capacity = ps->top = 0;
    15. }
    16. //出栈和入栈
    17. void StackPush(Stack* ps, SDateType x)
    18. {
    19. assert(ps);
    20. //扩容
    21. if (ps->top == ps->capacity)
    22. {
    23. SDateType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    24. SDateType* tmp = (SDateType*)realloc(ps->a,newcapacity*sizeof(SDateType));
    25. if (tmp == NULL)
    26. {
    27. perror("realloc fail:");
    28. return;
    29. }
    30. ps->a = tmp;
    31. ps->capacity = newcapacity;
    32. }
    33. //尾插
    34. ps->a[ps->top] = x;
    35. ps->top++;
    36. }
    37. void StackPop(Stack* ps)
    38. {
    39. assert(ps);
    40. assert(ps->top > 0);//只少有一个元素,才能删除
    41. ps->top--;
    42. }
    43. //栈的有效个数和栈顶元素
    44. int StackSize(Stack* ps)
    45. {
    46. assert(ps);
    47. return ps->top;
    48. }
    49. int StackTop(Stack* ps)
    50. {
    51. assert(ps);
    52. assert(ps->top > 0);
    53. return ps->a[ps->top - 1];
    54. }
    55. //栈是否为空
    56. bool StackEmpty(Stack* ps)
    57. {
    58. assert(ps);
    59. return ps->top == 0;
    60. }

    二、队列

    2.1  队列的概念及结构

    队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)的原则。

    入队列进行插入操作的一端称为队尾

    出队列进行删除操作的一端称为队头

    2.2  队列的实现(单链表队列)

    队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数 组头上出数据,效率会比较低。

    2.2.1 队列的基本功能实现

    1. #include
    2. #include
    3. #include
    4. #include
    5. typedef int QDateType;
    6. typedef struct QueueNode
    7. {
    8. QDateType val;
    9. struct QueueNode * next;
    10. }QueueNode;
    11. typedef struct Queue
    12. {
    13. QueueNode *head;
    14. QueueNode *tail;
    15. QDateType size;
    16. }Queue;
    17. // 初始化队列
    18. void QueueInit(Queue* pq);
    19. void QueueDestroy(Queue* pq);
    20. // 队尾入列和出列
    21. void QueuePush(Queue* pq, QDateType x);
    22. void QueuePop(Queue* pq);
    23. // 返回队头和队尾
    24. QDateType QueueFront(Queue* pq);
    25. QDateType QueueBack(Queue* pq);
    26. // 获取队列中有效元素个数
    27. int QueueSize(Queue* pq);
    28. // 检测队列是否为空
    29. bool QueueEmpty(Queue* pq);
    2.2.1.1 队列的初始化和销毁
    1. // 初始化队列
    2. void QueueInit(Queue* pq)
    3. {
    4. assert(pq);
    5. pq->head = pq->tail = NULL;
    6. pq->size = 0;
    7. }
    8. //队列的销毁
    9. bool QueueEmpty(Queue* pq)
    10. {
    11. assert(pq);
    12. return pq->head==NULL;
    13. }
    2.2.1.2 入列和出列
    1. //入列
    2. void QueuePush(Queue* pq, QDateType x)
    3. {
    4. assert(pq);
    5. QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));
    6. node->val = x;
    7. node->next = NULL;
    8. if (pq->tail == NULL)
    9. {
    10. pq->head = pq->tail = node;
    11. pq->size++;
    12. }
    13. else
    14. {
    15. pq->tail->next = node;
    16. pq->tail = node;
    17. pq->size++;
    18. }
    19. }
    20. //出列
    21. void QueuePop(Queue* pq)
    22. {
    23. assert(pq);
    24. assert(pq->head != NULL);//只少保证一个节点
    25. QueueNode* del = pq->head;
    26. pq->head = pq->head->next;
    27. free(del);
    28. del = NULL;
    29. pq->size--;
    30. if (pq->head == NULL)//只有一个节点处理
    31. {
    32. pq->tail = NULL;
    33. }
    34. }
    2.2.1.3    返回队头和队尾元素
    1. // 返回队头和队尾
    2. QDateType QueueFront(Queue* pq)
    3. {
    4. assert(pq);
    5. return pq->head->val;
    6. }
    7. QDateType QueueBack(Queue* pq)
    8. {
    9. assert(pq);
    10. return pq->tail->val;
    11. }
    2.2.1.4  队列元素个数
    1. // 获取队列中有效元素个数
    2. int QueueSize(Queue* pq)
    3. {
    4. assert(pq);
    5. return pq->size;
    6. }
    2.2.1.5  队列是否为空
    1. bool QueueEmpty(Queue* pq)
    2. {
    3. assert(pq);
    4. return pq->head==NULL;
    5. }

    2.2.2  Queue.h

    1. #include
    2. #include
    3. #include
    4. #include
    5. typedef int QDateType;
    6. typedef struct QueueNode
    7. {
    8. QDateType val;
    9. struct QueueNode * next;
    10. }QueueNode;
    11. typedef struct Queue
    12. {
    13. QueueNode *head;
    14. QueueNode *tail;
    15. QDateType size;
    16. }Queue;
    17. // 初始化队列
    18. void QueueInit(Queue* pq);
    19. void QueueDestroy(Queue* pq);
    20. // 队尾入列和出列
    21. void QueuePush(Queue* pq, QDateType x);
    22. void QueuePop(Queue* pq);
    23. // 返回队头和队尾
    24. QDateType QueueFront(Queue* pq);
    25. QDateType QueueBack(Queue* pq);
    26. // 获取队列中有效元素个数
    27. int QueueSize(Queue* pq);
    28. // 检测队列是否为空
    29. bool QueueEmpty(Queue* pq);

    2.2.1 Queue.c

    1. #include"Queue.h"
    2. // 初始化队列
    3. void QueueInit(Queue* pq)
    4. {
    5. assert(pq);
    6. pq->head = pq->tail = NULL;
    7. pq->size = 0;
    8. }
    9. void QueuePush(Queue* pq, QDateType x)
    10. {
    11. assert(pq);
    12. QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));
    13. node->val = x;
    14. node->next = NULL;
    15. if (pq->tail == NULL)
    16. {
    17. pq->head = pq->tail = node;
    18. pq->size++;
    19. }
    20. else
    21. {
    22. pq->tail->next = node;
    23. pq->tail = node;
    24. pq->size++;
    25. }
    26. }
    27. void QueuePop(Queue* pq)
    28. {
    29. assert(pq);
    30. assert(pq->head != NULL);//只少保证一个节点
    31. QueueNode* del = pq->head;
    32. pq->head = pq->head->next;
    33. free(del);
    34. del = NULL;
    35. pq->size--;
    36. if (pq->head == NULL)//只有一个节点处理
    37. {
    38. pq->tail = NULL;
    39. }
    40. }
    41. // 返回队头和队尾
    42. QDateType QueueFront(Queue* pq)
    43. {
    44. assert(pq);
    45. return pq->head->val;
    46. }
    47. QDateType QueueBack(Queue* pq)
    48. {
    49. assert(pq);
    50. return pq->tail->val;
    51. }
    52. // 获取队列中有效元素个数
    53. int QueueSize(Queue* pq)
    54. {
    55. assert(pq);
    56. return pq->size;
    57. }
    58. bool QueueEmpty(Queue* pq)
    59. {
    60. assert(pq);
    61. return pq->head==NULL;
    62. }
    63. void QueueDestroy(Queue* pq)
    64. {
    65. assert(pq);
    66. QueueNode* cur = pq->head;
    67. while (cur)
    68. {
    69. QueueNode* next = cur->next;
    70. free(cur);
    71. cur = next;
    72. }
    73. pq->head = pq->tail = NULL;
    74. pq->size = 0;
    75. }

  • 相关阅读:
    第三十二章 管理许可(五)
    Excel 快速分析
    你适合做自动化测试吗?
    【MySQL知识点】默认约束、非空约束
    第二部分 Makefile 总述
    【React学习】React高级特性
    【每日一题】回文串移除方案
    tensor类型、属性、torch.tensor与torch.Tensor的区别
    k线图形态这样记(口诀篇)
    学习笔记(1)
  • 原文地址:https://blog.csdn.net/zhoubancheng/article/details/134493745