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)。
 

0 0
原创粉丝点击