数据结构之栈

来源:互联网 发布:问卷调查数据分析方法 编辑:程序博客网 时间:2024/06/04 23:32

栈的定义

栈(stack)是限定于在表尾进行插入和删除操作的线性表
可以理解为后进先出,先进后出的数据结构

栈的基本操作

1.Push
将数据压入栈中,压出的数据成为新的栈顶
2.Pop
获取栈顶数据,并释放,原栈顶后一个元素成为新栈顶



栈的分类

1.顺序存储结构栈

用一段内存作为栈的存储空间,top指向栈顶元素的下标

2.共享空间栈

两个类型的栈共享一段内存,适用于此消彼长型的数据情况。top1指向栈1的栈顶,top2指向栈2的栈顶,当top1与top2碰头则栈空间不足。

3.链栈

     就是一个只允许在线性链表表头插入删除的线性链表top为指向链表节点的指针。
C实现

1.顺序结构栈

栈结构为
typedef struct item//普通栈{int buffer[MAX_SIZE];//这个其实可以动态分配int top=-1;}Stack;
MAX_SIZE为一个宏定义

Push操作
bool Push(Stack *L,int *arry,int lenth){if (MAX_SIZE - L->top - 1<lenth)return 0;//看空间是否足够for (int i = 0; i < lenth; i++){L->top++;L->buffer[L->top] = arry[i];}return 1;}

该操作允许向栈中压入一组数据,会进行对栈空间进行计算,如果栈空间不够(MAX_SIZE-L->top-1)则返回0,压入成功返回1

Pop操作
bool Pop(Stack *L, int *e){if (L->top == -1)return 0;*e = L->buffer[L->top];L->top--;return 1;}
弹出操作会先判断栈中是否有数据即栈顶知否指向-1,如果是则表示栈为空返回0,否则返回栈顶数据。

因为插入与弹出操作均未涉及到循环所以其时间复杂度为O(1)

2.共享空间栈

栈结构:
typedef struct date//共享空间栈{int buffer[MAX_SIZE];int top1=-1;int top2=MAX_SIZE;}SqlStack;

top1指向数组的底部  top2指向数据的顶部 MAX_SIZE依然是对数组长度的宏定义

Push操作
bool Push(SqlStack *L,int *arry,int lenth,int Stacknum)//适用于两栈共享{if (L->top1 + lenth > L->top2)return 0;//没有存储空间了if (Stacknum == 1){for (int i = 0; i < lenth; i++){L->top1++;L->buffer[L->top1] = arry[i];}}else if (Stacknum == 2){for (int i = 0; i < lenth; i++){L->top2--;L->buffer[L->top2] = arry[i];}}else return 0;return 1;}
该操作依然允许压入一组数据,并且需要指出压入栈1或者压入栈2,当top1与top2碰面则表示该栈空间已不足返回0,否则完成操作后返回1


Pop操作
bool Pop(SqlStack *L,int *date,int Stacknum){if (L->top1 == -1 && L->top2 == MAX_SIZE)return 0;//栈中没有数据if (Stacknum == 1){*date = L->buffer[L->top1];L->top1--;}else if (Stacknum == 2){*date = L->buffer[L->top2];L->top2++;}else return 0;return 1;}

弹出栈顶元素的数据,这里判断空栈的方式是top1=-1并且top2=MAX_SIZE


3.链栈

数据结构:
节点:
typedef struct obj{int num = 0;obj*next = NULL;}StackNode,*LinkStackPtr;


栈结构:
typedef struct element{LinkStackPtr top=NULL;int count;}LinkStack;//链栈

Push操作:
bool Push(LinkStack *L,int date)//新加入的元素会在顶部{LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));s->num = date;s->next = L->top;L->top = s;L->count++;return 1;}

该操作会先创建一个链节点s为其分配存储空间 s的向后指针next指向栈顶之后栈顶指针指向s,此时操作结束top指向s,s指向栈原栈顶元素
Pop操作:
bool Pop(LinkStack *L,StackNode *e){LinkStackPtr ptr;if (L->top==NULL)return 0;e->num = L->top->num;ptr = L->top;L->top = L->top->next;free(ptr);L->count--;return 1;}
该操作依然会先对链栈进行判断是否是空链栈,判断方式可以是判断count的值,也可以判断top指针是否为空
copy一个节点元素并将其复制给e所在地址的元素返回。