当前位置:   article > 正文

【c语言】栈(通过数组和链表实现)

【c语言】栈(通过数组和链表实现)

目录

栈的简介

通过数组实现栈:

通过链表实现栈:

注意事项:


栈的简介

栈是一种数据结构,它是一个具有特殊性质的线性表。栈中的元素遵循后进先出(LIFO,Last In First Out)的原则,也就是最后入栈的元素最先被弹出。

在C语言中,栈通常是由系统分配的一段连续内存空间,它用来存储局部变量、函数参数以及函数调用的返回地址等信息。每当一个函数被调用时,系统都会为其分配一个栈帧,用来存储这些信息,然后将其压入栈中。当函数执行完毕后,系统会将栈帧弹出,恢复先前的执行状态。

在C语言中,栈的操作主要包括压栈(push)、弹栈(pop)以及栈顶元素访问等。这些操作可以通过数组实现,也可以通过使用指针来操作栈。

通过数组实现栈:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int MAXSIZE = 8;
  4. int *stack;
  5. int top = -1;
  6. int isempty()
  7. {
  8. if(top == -1)
  9. return 1;
  10. else
  11. return 0;
  12. }
  13. int isfull()
  14. {
  15. if(top == MAXSIZE - 1)
  16. return 1;
  17. else
  18. return 0;
  19. }
  20. int peek()
  21. {
  22. return stack[top];
  23. }
  24. int pop()
  25. {
  26. int data;
  27. if(!isempty())
  28. {
  29. data = stack[top];
  30. top = top - 1;
  31. printf("Popping data: %d\n", data);
  32. return data;
  33. }
  34. else
  35. {
  36. printf("Could not retrieve data, Stack is empty.\n");
  37. return -1;
  38. }
  39. }
  40. void push(int data)
  41. {
  42. if(isfull())
  43. {
  44. // Increase size of stack by 2x
  45. MAXSIZE *= 2;
  46. stack = (int *) realloc(stack, MAXSIZE * sizeof(int));
  47. printf("Stack size doubled to %d\n", MAXSIZE);
  48. }
  49. top = top + 1;
  50. stack[top] = data;
  51. printf("Pushing data: %d\n", data);
  52. }
  53. int main() {
  54. // Allocate memory for stack
  55. stack = (int *) malloc(MAXSIZE * sizeof(int));
  56. // Push items on to the stack
  57. push(1);
  58. push(2);
  59. push(3);
  60. push(4);
  61. push(5);
  62. push(6);
  63. push(7);
  64. push(8);
  65. push(9);
  66. push(10);
  67. printf("Stack full: %s\n", isfull()?"true":"false");
  68. printf("Stack empty: %s\n", isempty()?"true":"false");
  69. printf("Element at top of the stack: %d\n" ,peek());
  70. // Print stack data
  71. while(!isempty()) {
  72. int data = pop();
  73. //printf("%d\n",data);
  74. }
  75. printf("Stack full: %s\n", isfull()?"true":"false");
  76. printf("Stack empty: %s\n", isempty()?"true":"false");
  77. // Free memory allocated for stack
  78. free(stack);
  79. return 0;
  80. }

这段代码是一个用C语言实现的栈的数据结构示例。其中包含了栈的基本操作,如初始化、判断栈是否为空、判断栈是否已满、获取栈顶元素、弹出栈顶元素以及压入新元素等。

isempty()函数:

这段代码是定义了一个名为isempty的函数,用来判断栈是否为空。函数中判断栈顶指针top的值是否为-1,如果是,则栈为空,返回1;否则,栈不为空,返回0。

isfull()函数:

这段代码是实现判断栈是否已满的函数,函数名为isfull()。在这个函数中,首先通过判断栈顶指针top是否等于栈的最大容量MAXSIZE-1,来确定栈是否已满。如果是,则返回1,表示栈已满;否则,返回0,表示栈未满。这个函数的返回值可以用于在主函数中判断是否可以继续往栈中添加数据。

peek()函数:

这段代码定义了一个函数peek(),用于返回栈顶元素的值,但是并不弹出栈顶元素。具体实现是直接返回存储在数组stack中的top位置的元素。需要注意的是,在调用peek()函数之前需要先确保栈不为空,否则将访问无效内存。

pop()函数:

这段代码实现了从栈中弹出(或删除)一个元素,并返回该元素的值。首先它定义了一个整数变量data,用于存储要删除的元素的值。然后它检查栈是否为空,如果不是,则将栈顶元素的值存储在data变量中,并将栈顶指针top向下移动一位以删除该元素。最后,它打印出被删除元素的值,然后将该值返回。如果栈为空,则打印出一条消息说明无法检索数据,然后返回-1表示出现了错误。

push(int data)函数:

这段代码实现了栈数据结构的 push 操作,即向栈顶添加元素。首先,它检查栈是否已经满了,如果是,则将 MAXSIZE 扩大为原来的两倍,通过 realloc 函数重新分配内存空间,并打印出新的栈的大小。然后将 top 指针指向栈顶元素的下一个位置,将 data 元素添加到这个位置,最后打印出“Pushing data:”和添加的元素值。

通过链表实现栈:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义栈的节点结构体
  4. typedef struct Node {
  5. int data; // 数据
  6. struct Node* next; // 指向下一个节点的指针
  7. } Node;
  8. // 定义栈结构体
  9. typedef struct Stack {
  10. Node* top; // 指向栈顶节点的指针
  11. int size; // 栈的大小
  12. } Stack;
  13. // 初始化栈
  14. Stack* init() {
  15. Stack* stack = (Stack*)malloc(sizeof(Stack)); // 分配内存空间
  16. stack->top = NULL; // 栈顶初始化为空
  17. stack->size = 0; // 栈的大小初始化为0
  18. return stack;
  19. }
  20. // 入栈操作
  21. void push(Stack* stack, int data) {
  22. Node* node = (Node*)malloc(sizeof(Node)); // 分配内存空间
  23. node->data = data; // 将数据赋值给节点
  24. node->next = stack->top; // 新节点指向当前栈顶节点
  25. stack->top = node; // 栈顶指针指向新节点
  26. stack->size++; // 栈大小加1
  27. }
  28. // 出栈操作
  29. int pop(Stack* stack) {
  30. if (stack->top == NULL) { // 栈为空,无法出栈
  31. printf("栈为空,无法出栈\n");
  32. return -1;
  33. }
  34. int data = stack->top->data; // 获取栈顶节点的数据
  35. Node* node = stack->top; // 保存栈顶节点指针
  36. stack->top = stack->top->next; // 栈顶指针指向下一个节点
  37. free(node); // 释放栈顶节点的内存空间
  38. stack->size--; // 栈大小减1
  39. return data;
  40. }
  41. // 获取栈顶元素
  42. int peek(Stack* stack) {
  43. if (stack->top == NULL) { // 栈为空,无法获取栈顶元素
  44. printf("栈为空,无法获取栈顶元素\n");
  45. return -1;
  46. }
  47. return stack->top->data; // 返回栈顶节点的数据
  48. }
  49. // 判断栈是否为空
  50. int isEmpty(Stack* stack) {
  51. return stack->size == 0;
  52. }
  53. // 主函数,测试代码
  54. int main() {
  55. Stack* stack = init(); // 初始化栈
  56. push(stack, 1); // 入栈
  57. push(stack, 2); // 入栈
  58. push(stack, 3); // 入栈
  59. printf("%d\n", peek(stack)); // 获取栈顶元素
  60. printf("%d\n", pop(stack)); // 出栈
  61. printf("%d\n", pop(stack)); // 出栈
  62. printf("%d\n", pop(stack)); // 出栈
  63. printf("%d\n", pop(stack)); // 出栈,此时栈已为空,无法再出栈
  64. return 0;
  65. }

这段代码实现了基于链表的栈结构,包括了栈的初始化、入栈、出栈、获取栈顶元素和判断栈是否为空等操作。

init()函数:

这段代码是用来初始化栈的函数。首先,使用malloc()函数为Stack类型的结构体分配内存空间,然后将分配的空间强制转换为Stack指针类型,以便在栈结构体中使用它。然后将指向栈顶节点的指针top初始化为NULL,表示当前栈为空。栈的大小size被初始化为0,因为栈当前没有任何元素。最后,函数返回栈的指针。

push(Stack* stack, int data)函数:

这段代码实现了栈的入栈操作。函数的第一个参数是指向栈结构体的指针,第二个参数是要入栈的数据。函数首先通过调用 malloc 函数来分配内存空间以创建一个新的节点(Node)。然后将要入栈的数据赋值给该节点的 data 成员变量。接着,将该节点的 next 成员变量指向当前栈顶节点,以便将新节点插入到栈顶。最后,更新栈顶指针和栈的大小,使其指向新的节点并将大小加1,完成入栈操作。

pop(Stack* stack)函数:

这段代码实现了出栈操作。首先判断栈是否为空,若为空则无法进行出栈操作,输出提示信息并返回-1。否则,获取栈顶节点的数据,保存栈顶节点指针,栈顶指针指向下一个节点,释放栈顶节点的内存空间,栈大小减1,最后返回栈顶节点的数据。这个过程中,节点的next指向了下一个节点,保证了栈的后进先出的特性。、

peek(Stack* stack)函数:

这段代码是用来获取栈顶元素的函数。它接受一个指向栈结构体的指针,如果栈为空则打印出错信息并返回 -1,否则返回栈顶节点的数据。它的实现非常简单,只需要判断栈顶指针是否为空,如果不为空则返回栈顶节点的数据。

isEmpty(Stack* stack)函数:

这段代码实现了一个判断栈是否为空的函数。它接受一个指向栈的指针,并返回一个整数值。如果栈的大小为0,即栈为空,函数返回1;否则返回0。该函数的实现非常简单,只需要比较栈的大小和0即可。如果栈的大小为0,就意味着栈中没有元素,即为空。

注意事项:

在学习栈的过程中,我们需要注意理解栈的基本概念和特性,栈是一种先进后出的数据结构,只允许在栈顶进行插入和删除操作。理解栈的这些基本概念和特性是理解和使用栈的基础。还要学会使用栈的基本操作,栈的基本操作包括入栈、出栈、获取栈顶元素、判断栈是否为空等。学会使用这些基本操作,可以更加灵活地使用栈。还有学习栈的实现方式,栈可以用数组或链表实现。了解这两种实现方式的优缺点、适用场景以及如何实现可以帮助更好地理解栈。以及熟练掌握栈的应用场景,栈在实际应用中有很多常见的场景,如函数调用栈、表达式求值、括号匹配等。掌握栈的应用场景,可以更好地应用栈解决实际问题。还要注意栈的内存管理,使用栈时需要注意内存管理,尤其是使用动态内存分配的实现方式时,需要及时释放分配的内存,避免内存泄漏。

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

闽ICP备14008679号