C语言实现栈数据结构操作
来源:互联网 发布:js 获取map 的键和值 编辑:程序博客网 时间:2024/04/29 17:32
定义:栈是限定仅在表尾进行插入和删除操作的线性表。
把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表,简称为LIFO。
栈的插入操作,叫做进栈,也称为压栈或者入栈。
栈的删除操作,叫做出栈,也称为弹栈。
栈的顺序存储结构
因为栈是线性表的一种特殊形式,所以用数组实现栈的顺序存储结构。
我们约定,下标为0的一端作为栈底。定义一个top变量来指示栈顶元素在数组中的位置。约定把空栈的判定条件定为top等于-1。
栈的结构定义:
#define MAXSIZE 100;typedef int SElemType;typedef struct{SElemType data[MAXSIZE];int top; /*用于栈顶指针*/ }SqStack;
栈的顺序存储结构-----进栈
C语言代码如下:
/*插入元素e为新的栈顶元素*/int Push(SqStack *S, SElemType e){if (S->top == MAXSIZE - 1){return 0;}S->top++;S->data[S->top] = e;return 1;}
栈的顺序存储结构---出栈
C语言代码如下:
/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0*/int Pop(SqStack *L, SElemType *e){if (S->top == -1){return 0;}*e = S->data[S->top];return 1; }
说明:栈的顺序存储结构的进栈和出栈都没有涉及循环,时间复杂度都为O(1)。
两栈共享空间
如果有两个相同类型的栈,我们为他们各自开辟了数组空间,极有可能是第一个栈满了 ,再进栈就溢出了,而另一个栈还有很多存储空间空闲。因此我们完全可用一个数组来存储两个栈。
做法:数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈的栈底为栈的末端,即下标为n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。
我们约定top1和top2是两个栈的栈顶指针。
栈1为空时,top1=-1;栈2空时,top2=n。
当栈满时有top2 = top1+1。
两栈共享空间结构代码如下:
/*两栈共享空间结构*/typedef struct{SElemType data[MAXSIZE];int top1;int top2;}SqDoubleStack;
两栈共享空间的进栈操作
/*插入元素e为新的栈顶元素*/int Push(SqDoubleStack *S, SElemType e, int stackNumber){if (S->top1+1==S->top2) /*栈已经满,不能再push新元素*/{return 0;}if (stackNumber == 1) /*栈1有元素进栈*/{S->data[++S->top1] = e /*若栈1则先top1+1后给数组元素赋值*/ } else if(stackNumber == 2){S->data[--S->top2] = e;} return 1;}
两栈共享空间出栈操作
/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回1,否则返回0*/int Pop(SqDoubleStack *S, SElemType *e, int stackNumber){if (stackNumber == 1){if (S->top1 == -1){return 0;}*e = S->data[S->top1--];}else if (stackNumber == 2){if (S->top2 == MAXSIZE){return 0;}*e = S->data[S->top2++];}return 1;}
说明:使用两栈共享空间这样的数据结构,通常都是当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况。当然,这只是针对两个具有相同数据类型的栈的一个设计上的技巧。
栈的链式存储结构----简称链栈
由于单链表有头指针,而栈顶指针也是必须的,因此比较好的方法时把栈顶放在单链表的头部。通常对于链栈来说,是不需要头结点的。
链栈的结构定义:
typedef int SElemType;typedef struct StackNode{SElemType data;struct StackNode *next; }StackNode;typedef StackNode * LinkStackPtr;typedef struct LinkStack{LinkStackPtr top; //栈顶指针 int count;}LinkStack;
链栈的进栈操作:
/*插入元素e为新的栈顶元素*/int Push(LinkStack *S, SElemType e){LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));s->data = e;s->next = S->top;//把当前的栈顶元素赋值给新结点的直接后继S->top = s;S->count++;return 1; }
链栈的出栈操作:
/*若栈不为空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0*/int Pop(LinkStack *S, SElemType *e){LinkStackPtr p;if (S->top == NULL){return 0;}*e = S->top->data;p = S->top; S->top = S->top->next; free(p); S->count--;return 1; }
说明:对于链栈的进栈和出栈操作,它们的时间复杂度都为O(1)。
- C语言实现栈数据结构操作
- C语言------数据结构(栈操作,数组实现)
- 算法与数据结构-栈的基本操作C语言实现
- 数据结构C语言实现栈
- 数据结构.栈(C语言实现)
- 数据结构---栈C语言实现
- 数据结构栈C语言实现
- C语言数据结构栈的操作集
- 数据结构---C语言顺序栈基本操作
- 数据结构(C语言实现)
- 数据结构C语言实现
- 数据结构(C语言实现)
- 数据结构.二叉树的基本操作(C语言实现)
- 数据结构之---c语言实现循环单链表操作
- 数据结构之---c语言实现双向链表操作
- 数据结构 单链表插入删除操作(c语言实现)
- 《数据结构与算法》-单链表基本操作的C语言实现
- 数据结构--单链表的基本操作(C语言实现)
- Boot block
- 详解Java异常处理——自动异常处理
- Remove Duplicates from Sorted List II
- 如何提高行动力【】
- 2. 机器学习应用案例
- C语言实现栈数据结构操作
- 项目视频讲解_java邮件开发视频教程
- Android之邮箱注册正则表达式
- Android 使用正则表达式验证邮箱格式是否正确
- el表达式怎样取关键字带有点的属性的值,比如key="struts.valueStack"
- 去掉编译内核的优化选项
- 高校平台--环境理解之有状态和无状态会话bean
- 打造Linux下Vim之(二)vim中设置工作路径
- 第7天:散列HASH(四)冲突解决办法之外部拉链法