• 数据结构:(c实现)手把手教你实现栈和队列(内附详细代码)


    目录:

    一:栈

    (1)栈的基本概念(物理图解)

    (2)栈的基本结构以及初始化

    (3)栈的基本接口函数(入栈与出栈)

     二:队列

    (1)基本概念与图解

    (2)基本接口函数的实现

    一:栈

    (1)栈的基本概念(物理图解)

    在标准规定里,栈是一种特殊的线性表,有栈底和栈顶两端,规定它只能从栈顶出入数据,所以这也是栈的一个基本原则:先入栈的后出栈(后入栈先出栈)我们在实现一个栈时,通常使用顺序表来实现,以顺序表的表尾来做栈顶

    例如上面的一个栈,栈底的位置一直不改变从栈顶进一个数据(指向栈顶的指针加一),然后又从栈顶出一个数据(指向栈顶的指针减一)。

    (2)栈的基本结构以及初始化

    1. typedef int Stack_data_type;
    2. #define Maxca 10
    3. typedef struct Stack
    4. {
    5. Stack_data_type * St;
    6. int top;
    7. int capacity;
    8. }stack;
    9. //栈初始化
    10. void Stack_init(stack* ps)
    11. {
    12. ps->capacity = Maxca;
    13. ps->top = 0;
    14. ps->St = (Stack_data_type*)malloc(ps->capacity * sizeof(Stack_data_type));
    15. }

    在栈的初始化时,top指针初始值设置为0,每次添加数据后,top++,所以top一直指向着栈内最后一个数据的下一个数据节点。(图解如下)

    (3)栈的基本接口函数(入栈与出栈)

    1. //入栈
    2. void Stack_push(stack* ps, Stack_data_type x)
    3. {
    4. ps->St[ps->top] = x;
    5. ps->top++;
    6. if (ps->top == ps->capacity)
    7. {
    8. Stack_data_type* ptr = (Stack_data_type*)realloc(ps->St, ps->capacity * 2 * sizeof(Stack_data_type));
    9. if (ptr == NULL)
    10. {
    11. perror(realloc);
    12. }
    13. else
    14. {
    15. ps->St = ptr;
    16. ps->capacity *= 2;
    17. }
    18. }
    19. }
    20. //出栈
    21. Stack_data_type Stack_pop(stack* ps)
    22. {
    23. if (ps->top == 0)
    24. {
    25. printf("栈已经清空\n");
    26. exit(-1);
    27. }
    28. else
    29. {
    30. ps->top--;
    31. printf("出栈%d \n", ps->St[ps->top]);
    32. return ps->St[ps->top];
    33. }
    34. }

    这里需要注意的是,当栈慢的时候需要自动开辟新的空间。还有在对栈进行出栈操作时,要判断top是否为0,当top为0时,代表栈已经清空了。

     二:队列

    (1)基本概念与图解

    队列:基本概念,该结构只能从一端入数据,另一端出数据。所以这也是队列的特殊属性,先入队列的数据先出队列,后入队列的数据后出队列。(先进先出,后进后出)

    在实现这种结构时,一般推荐使用单链表。定义两个指针去维护这个单链表,一个指向表头,一个指向表尾。有数据入队列时就尾插,出数据就头删。并且将指向头位置的指针向后移动一位。 

    (2)基本接口函数的实现

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include"Queue.h"
    3. //初始化
    4. void Queue_init(que* ps)
    5. {
    6. ps->head = ps->tail = NULL;
    7. }
    8. //入队
    9. void Queue_push(que* ps, Queue_data_type x)
    10. {
    11. assert(ps);
    12. Queue* newnode = (Queue*)malloc(sizeof(Queue));
    13. newnode->data = x;
    14. newnode->next = NULL;
    15. if (ps->head == NULL)
    16. {//说明此时还没有节点
    17. ps->head = ps->tail = newnode;
    18. }
    19. else
    20. {
    21. ps->tail->next = newnode;
    22. ps->tail = newnode;
    23. }
    24. }
    25. //出队
    26. Queue_data_type Queue_pop(que* ps)
    27. {
    28. assert(ps);
    29. assert(ps->head);
    30. Queue_data_type tmp =0;
    31. Queue* cur = NULL;
    32. if (ps->head->next == NULL)
    33. {
    34. tmp = ps->head->data;
    35. free(ps->head);
    36. return tmp;
    37. }
    38. else
    39. {
    40. tmp = ps->head->data;
    41. cur = ps->head->next;
    42. free(ps->head);
    43. ps->head =cur;
    44. return tmp;
    45. }
    46. }
    47. //打印栈
    48. void Queue_Prin(que* ps)
    49. {
    50. Queue* cur = ps->head;
    51. assert(ps && ps->head);
    52. while (cur)
    53. {
    54. printf("%d ", cur->data);
    55. cur = cur->next;
    56. }
    57. printf("\n");
    58. }
    59. //释放队列
    60. void Queue_release(que* ps)
    61. {
    62. assert(ps && ps->head);
    63. Queue* cur = ps->head;
    64. Queue* next = cur->next;
    65. while (cur->next)
    66. {
    67. free(cur);
    68. cur = next;
    69. next = next->next;
    70. }
    71. free(cur);
    72. }

  • 相关阅读:
    Ansible循环与判断
    ssh 免密登陆
    [HUBUCTF 2022 新生赛]ezPython
    【elasticsearch】记录ES查询数据结果为空的问题(单个字搜索可以,词语搜索为空)
    递归,动态规划实现
    Google Earth Engine ——利用公开的河流数据计算河流的有效宽度
    YoloR:又一个YOLO系列新框架!速度远远高于Yolov4(代码已开源)
    HTTP与SOCKS-哪种协议更适合您的代理需求?
    Doris学习笔记之备份与恢复
    Java面向对象编程
  • 原文地址:https://blog.csdn.net/qq_51004011/article/details/124904385