您的位置:首页 > 其它

栈与队列->栈,链栈

2013-07-23 11:19 253 查看

栈,仅限定在栈顶(表尾)进行插入和删除的线性表。其操作特性,后进先出。

栈顶(top):表尾端,允许进行插入和删除的一端;

栈底(bottom):表头端,不允许进行插入和删除;

栈的顺序存储结构

栈的顺序存储结构,是指分配一块连续的存储单元,存放栈中的元素,并同时符设一个变量(top)指向当前栈顶的元素。

#define MAXSIZE 20
typedef struct {
Elemtype data[MAXSIZE];
int top;
}SqStack;


栈顶指针:S.top,初始化时为-1,栈顶元素为S.data[S.top]

进栈操作:栈不满是,栈顶指针加1,在将值送人栈顶位置;

出栈操作:栈不空时,先取栈顶指针数据,然后再将栈顶指针减1;

栈空条件:S.top = -1

栈满条件:S.top = MAXSIZE - 1

栈长: S.top + 1

初始化代码:

s.top = -1;


判断栈空代码:

if(s.top == -1)
return true;
else
return false;


进栈操作:

if(S.top == MAXSIZE - 1)
return false;

S.data[++S.top] = x;


出栈操作:
if(S.top == -1)
return false;

x = S.data[S.top--];


栈顶指针指向的元素就是栈顶元素,所以进栈的时候操作是S.data[++S.top] = x; 出栈的时候操作是X = S.data[S.top --];

/************************************************************************************************
顺序栈和链栈的时间复杂度都一样是O(1)。
对于空间性能:
顺序栈需要事先确定固定的长度,肯能出现内存浪费的问题,但是其存取时定位很方便。
链栈则要求每个元素都有指针域,这同时也增加了内存开销,但是链栈可用于长度未知,或无限。

如果栈的使用过程中元素变化不可预料,有时会很小,有时会很大,那么最好是链栈。
反之,如果是在可控范围内,那么建议使用顺序栈会好些。

************************************************************************************************/
#define MAXSIZE 20  //存储空间初始分配量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

/************************************************************************************************
链栈:栈的链式存储结构(把栈顶放在单链表的头部,通常链栈不需要头结点)

对于链栈,基本上不存在栈满情况,除非内存已经没有可以使用的空间,如果真的发生,此时的操作系统面临死机崩溃的情况。
而不是链栈是否溢出的问题。

对于空栈来说,链表原定义是头指针指向空,那么链栈为空则为top=NULL;

************************************************************************************************/
#include <stdlib.h>
typedef int SElemType;   //SElemType 数据类型
typedef int Status;

typedef struct
{
SElemType data;
struct StackNode *next;
}StackNode, *LinkStackPtr;

typedef struct
{
LinkStackPtr top;
int count;
}LinkStack;

// 链栈的进栈操作  O(1)
// 栈顶插入元素,不用判断栈满
Status Push(LinkStack *S, SElemType e)
{
LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
s->data = e;
s->next = S->top;   // 把当前栈顶元素赋值给新结点的直接后继
S->top = s;         // 将新的结点s赋值给栈顶指针
S->count++;         // 站内元素个数增加
return OK;
}

// 链栈的出栈操作  O(1)
// 若栈不为空,则删除S的栈顶元素,并返回其值,并返回OK,否则Error
Status Pop(LinkStack *S, SElemType *e)
{
LinkStackPtr p;
if(StackEmpty(*S))  // S->top == NULL
return ERROR;

*e = S->top->data;      // 暂存定点元素
p = S->top;             // 将栈顶结点赋值给p
S->top = S->top->next;  // 把栈顶指针下移一位,指向后一结点
free(p);                // 释放结点P,原栈顶指针

S->count--;             // 栈总数减1
return OK;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: