赞
踩
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)
目录
(栈的相关操作类似于手枪子弹上膛,装弹时将子弹从上方一个个压入弹夹,开枪时最上面的子弹先被射出)
栈(stack)是限定仅在表尾插入和删除操作的线性表。
允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
不含任何数据元素的栈称为空栈特点:先进后出,后进先出
注意:
1 、栈又被称为后进先出( Last In First Out )的 线性表 ,简称 LIFO 结构
2 、栈的插入操作,称为 进栈 ,也称压栈、入栈( push )
3 、栈的删除操作,称为 出栈 ,也称为弹栈( pop )
顺序栈是利用一组连续存储单元依次存放栈底到栈顶的数据元素
- #define MAX_SIZE 255
-
- typedef struct {
- int id;
- char* name;
- }ElementType;
-
- /** 定义栈的顺序存储方式 */
- typedef struct SeqStack {
- ElementType elements[MAX_SIZE]; //顺序栈中用来存放数据元素的数组
- int top; //栈顶(数组中的下标),如果为-1则证明栈为空
- int length; //当前栈的元素个数
- }SeqStack;
初始化栈时我们需要将栈顶top赋值为-1,这样在后续操作时就可以对top进行加减,便于判断是否为满栈或者空栈
- /** 初始化栈 */
- void InitSeqStack(SeqStack* seqStack) {
- seqStack->top = -1; //栈顶指向-1的下标
- seqStack->length = 0;
- }
顺序栈的入栈操作只需要将数值赋给对应的数组下标即可(先判断是否可以插入)
- /** 向栈中压入元素,返回压入的结果(1/0) */
- int PushSeqStack(SeqStack* seqStack, ElementType element)
- {
- //判断是否满栈
- if (seqStack->top == MAX_SIZE - 1)
- {
- printf("满栈,压栈操作失败!");
- return 0;
- }
- seqStack->top++; //栈顶指针+1,以便加入新的元素
- //将新插入的元素赋值给栈顶
- seqStack->elements[seqStack->top] = element;
- seqStack->length++;
- return 1;
- }
- /** 以指针方式返回出栈的元素,返回值为出栈的结果(1/0) */
- int PopSeqStack(SeqStack* seqStack, ElementType* element)
- {
- if (seqStack->top == -1)
- {
- printf("空栈,出栈失败!\n");
- return 0;
- }
- //返回栈顶指向的元素
- *element = seqStack->elements[seqStack->top];
- seqStack->top--;
- seqStack->length--;
- return 1;
- }
- /** 清空栈 */
- void ClearSeqStack(SeqStack* seqStack)
- {
- seqStack->top = -1;
- seqStack->length = 0;
- }
链栈的结构与链表相似
插入与删除等操作都在链表的头部
即:链栈是一个以top为头结点、从栈顶指向栈底的单链表
- typedef struct
- {
- int id;
- const char* name;
- }ElementType;
-
- /** 链栈的结点 */
- typedef struct StackNode
- {
- ElementType data; //结点中保存的元素
- struct StackNode* next; //指向下个结点的指针
- }StackNode;
-
- /** 链栈结构 */
- typedef struct LinkedStack
- {
- StackNode* top; //栈顶指针
- int length; //链栈的长度(元素个数)
- }LinkedStack;
- void InitLinkedStack(LinkedStack* linkedStack)
- {
- linkedStack->top = NULL;
- linkedStack->length = 0;
- }
入栈时,和单链表(http://t.csdn.cn/yBFit)相似,只需要将新增的数据的next指向栈顶,然后将栈顶指向新增的数据
链栈无需判断是否满栈,因为链式结构几乎为无穷大
- /** 压栈并返回结果 */
- int PushLinkedStack(LinkedStack* linkedStack, ElementType element)
- {
- //创建一个新结点
- StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
- newNode->data = element;
- //新结点的next指向当前的栈顶
- newNode->next = linkedStack->top;
- linkedStack->top = newNode;
- linkedStack->length++;
- return 1;
- }
出栈有一点特殊,需要新创建一个结点保存要删除的结点数据,然后当top指向下一个结点后,释放新创建的结点,同时也就释放了要删除的结点
- int PopLinkedStack(LinkedStack* linkedStack, ElementType* element)
- {
- //判断栈是否为空
- if (linkedStack->top == NULL)
- {
- printf("空栈,出栈操作失败!\n");
- return 0;
- }
- //返回栈顶元素
- *element = linkedStack->top->data;
- //创建新结点,记录出栈操作前的栈顶指针
- StackNode* node = linkedStack->top;
- //栈顶指针下移一位
- linkedStack->top = linkedStack->top->next;
- //释放原栈顶空间
- free(node);
- linkedStack->length--;
- return 1;
- }
- /** 清空栈-遍历栈中的每个元素并释放结点空间 */
- void ClearLinkedStack(LinkedStack* linkedStack)
- {
- StackNode* tempNode;
- while (linkedStack->top)
- {
- tempNode = linkedStack->top;
- //栈顶指向下个元素
- linkedStack->top = linkedStack->top->next;
- free(tempNode);
- linkedStack->length--;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。