当前位置:   article > 正文

c语言数据结构-栈_c语言数据结构栈

c语言数据结构栈

 (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

初识栈: 

顺序栈:

初始化栈: 

 栈的插入(压栈):

 栈的删除(出栈):

清空栈: 

链栈: 

初始化栈: 

入栈: 

出栈: 

清空栈: 


初识栈: 

(栈的相关操作类似于手枪子弹上膛,装弹时将子弹从上方一个个压入弹夹,开枪时最上面的子弹先被射出)

栈(stack)是限定仅在表尾插入和删除操作的线性表。
允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
不含任何数据元素的栈称为空栈 

特点:先进后出,后进先出

 

注意:
1 、栈又被称为后进先出( Last In First Out )的 线性表 ,简称 LIFO 结构
2 、栈的插入操作,称为 进栈 ,也称压栈、入栈( push )
3 、栈的删除操作,称为 出栈 ,也称为弹栈( pop ) 

顺序栈

顺序栈是利用一组连续存储单元依次存放栈底到栈顶的数据元素 

  1. #define MAX_SIZE 255
  2. typedef struct {
  3. int id;
  4. char* name;
  5. }ElementType;
  6. /** 定义栈的顺序存储方式 */
  7. typedef struct SeqStack {
  8. ElementType elements[MAX_SIZE]; //顺序栈中用来存放数据元素的数组
  9. int top; //栈顶(数组中的下标),如果为-1则证明栈为空
  10. int length; //当前栈的元素个数
  11. }SeqStack;

初始化栈: 

初始化栈时我们需要将栈顶top赋值为-1,这样在后续操作时就可以对top进行加减,便于判断是否为满栈或者空栈

  1. /** 初始化栈 */
  2. void InitSeqStack(SeqStack* seqStack) {
  3. seqStack->top = -1; //栈顶指向-1的下标
  4. seqStack->length = 0;
  5. }

 栈的插入(压栈):

顺序栈的入栈操作只需要将数值赋给对应的数组下标即可(先判断是否可以插入) 

  1. /** 向栈中压入元素,返回压入的结果(1/0) */
  2. int PushSeqStack(SeqStack* seqStack, ElementType element)
  3. {
  4. //判断是否满栈
  5. if (seqStack->top == MAX_SIZE - 1)
  6. {
  7. printf("满栈,压栈操作失败!");
  8. return 0;
  9. }
  10. seqStack->top++; //栈顶指针+1,以便加入新的元素
  11. //将新插入的元素赋值给栈顶
  12. seqStack->elements[seqStack->top] = element;
  13. seqStack->length++;
  14. return 1;
  15. }

 栈的删除(出栈):

  1. /** 以指针方式返回出栈的元素,返回值为出栈的结果(1/0) */
  2. int PopSeqStack(SeqStack* seqStack, ElementType* element)
  3. {
  4. if (seqStack->top == -1)
  5. {
  6. printf("空栈,出栈失败!\n");
  7. return 0;
  8. }
  9. //返回栈顶指向的元素
  10. *element = seqStack->elements[seqStack->top];
  11. seqStack->top--;
  12. seqStack->length--;
  13. return 1;
  14. }

清空栈: 

  1. /** 清空栈 */
  2. void ClearSeqStack(SeqStack* seqStack)
  3. {
  4. seqStack->top = -1;
  5. seqStack->length = 0;
  6. }

链栈: 

链栈的结构与链表相似
插入与删除等操作都在链表的头部
即:链栈是一个以top为头结点、从栈顶指向栈底的单链表 

  1. typedef struct
  2. {
  3. int id;
  4. const char* name;
  5. }ElementType;
  6. /** 链栈的结点 */
  7. typedef struct StackNode
  8. {
  9. ElementType data; //结点中保存的元素
  10. struct StackNode* next; //指向下个结点的指针
  11. }StackNode;
  12. /** 链栈结构 */
  13. typedef struct LinkedStack
  14. {
  15. StackNode* top; //栈顶指针
  16. int length; //链栈的长度(元素个数)
  17. }LinkedStack;

初始化栈: 

  1. void InitLinkedStack(LinkedStack* linkedStack)
  2. {
  3. linkedStack->top = NULL;
  4. linkedStack->length = 0;
  5. }

入栈: 

入栈时,和单链表(http://t.csdn.cn/yBFit)相似,只需要将新增的数据的next指向栈顶,然后将栈顶指向新增的数据 

链栈无需判断是否满栈,因为链式结构几乎为无穷大

 

  1. /** 压栈并返回结果 */
  2. int PushLinkedStack(LinkedStack* linkedStack, ElementType element)
  3. {
  4. //创建一个新结点
  5. StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
  6. newNode->data = element;
  7. //新结点的next指向当前的栈顶
  8. newNode->next = linkedStack->top;
  9. linkedStack->top = newNode;
  10. linkedStack->length++;
  11. return 1;
  12. }

出栈: 

出栈有一点特殊,需要新创建一个结点保存要删除的结点数据,然后当top指向下一个结点后,释放新创建的结点,同时也就释放了要删除的结点

 

  1. int PopLinkedStack(LinkedStack* linkedStack, ElementType* element)
  2. {
  3. //判断栈是否为空
  4. if (linkedStack->top == NULL)
  5. {
  6. printf("空栈,出栈操作失败!\n");
  7. return 0;
  8. }
  9. //返回栈顶元素
  10. *element = linkedStack->top->data;
  11. //创建新结点,记录出栈操作前的栈顶指针
  12. StackNode* node = linkedStack->top;
  13. //栈顶指针下移一位
  14. linkedStack->top = linkedStack->top->next;
  15. //释放原栈顶空间
  16. free(node);
  17. linkedStack->length--;
  18. return 1;
  19. }

清空栈: 

  1. /** 清空栈-遍历栈中的每个元素并释放结点空间 */
  2. void ClearLinkedStack(LinkedStack* linkedStack)
  3. {
  4. StackNode* tempNode;
  5. while (linkedStack->top)
  6. {
  7. tempNode = linkedStack->top;
  8. //栈顶指向下个元素
  9. linkedStack->top = linkedStack->top->next;
  10. free(tempNode);
  11. linkedStack->length--;
  12. }
  13. }

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

闽ICP备14008679号