您的位置:首页 > 其它

栈:顺序栈和链式栈

2013-11-03 14:32 148 查看
        前面已经介绍了“链表”,包括顺序链表和链式链表。链表和栈都属于线性表,只是栈是一种特殊的线性表,其“只能够从一端(栈顶)进出”,必须遵循“先进后出”的原则。下面,我们简要学习一下顺序栈和链式栈。

(1)顺序栈

        与顺序存储的链表一样,顺序栈也是采用“数组”来存储。其数据结构如下:

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

        这里我们看出,栈和链表的数据结构几乎一模一样,只是里面的成员含义不同而已。在顺序链表里面,定义的是一个长度length,表示所能够存储的最大数据的个数,这个值是不能变化的;而顺序栈中定义的是栈顶元素的下标,这个值可以变化。

                  


       对于栈的操作来说,最重要的是“入栈”和“出栈”。这两个操作都必须遵循“FILO”的原则,其具体实现如下:

//入栈
bool Push(sqStack *S, Elemtype e)
{
if(S->top >= MAXSIZE - 1)
return false;
S->top++;    //要细心,不能单独用top,而是引用结构体中的元素
S->data[s->top] = e;
return true;
}
//出栈
bool Pop(sqStack *S, Elemtype *e)
{
if(S->top == 0)
return false;
*e = S->data[S->top];
S->top--;
return true;
}

        从上面的知识中,可以知道,顺序栈的操作很方便,但其最大的不足在于,必须事先确定数据存储的最大空间。这里,我们扩展一下知识,下面介绍一下如何做到两个顺序栈共享数据空间。这个方法的基本思想为:数组空间有两个端点,两个栈有两个栈底;让一个栈的栈底位于数组的起始端(下标为0处),让另一个栈的栈底位于数组的末端(下标为N-1处);如果要向栈里面添加元素,那么使栈顶向数组中间移动即可。

         


数据结构如下:

typedef struct
{
Elemtype data[MAXSIZE];
int top1;
int top2;
}sqDoubleStack;

入栈操作:

bool Push(sqDoubleStack *S, Elemtype e, int stackNumber)
{
if(S->top1+1 == S->top2)//特别注意,如果栈满了,top1和top2不是相等的,而是两者前后相邻,因此要加1
return false;
if(stackNumber == 1)
{
S->top1++;
S->data[S->top1] = e;
return true;
}
if(stackNumber == 2)
{
S->top2++;
S->data[S->top2] = e;
return true;
}
}

(2)链式栈

        链式存储的栈就不会存在“栈满”的现象。因此,在进行入栈、出栈的时候,就不用再判断是否满栈了。在对链式栈进行操作时,始终要把握一点:首先看到的是整个栈,而不每一个结点;对于整个栈,只有两个指标——栈顶指针(top)和栈元素个数(count);这样,我们就能够通过栈顶指针(top)来取到栈顶的一个结点,从而获取其中的数据data,并可以创建指针,移动指针位置,遍历栈中的各个元素。也就是说,我们必须“从栈(top、count),再到结点(data、next)”。

                                                     


其数据解结构可以定义为:

typedef struct StackNode
{
Elemtype data;
struct StackNode * next;
}StackNode, *LinkStackPtr;
typedef struct LinkStack
{
LinkStackPtr top;//这里top是一个stack结点类型的指针,指向Stack结点(栈顶)
int count;
}LinkStack;

入栈操作:

bool Push(LinkStack *S, Elemtype e)
{
LinkStackPtr tmp = (LinkStackPtr)malloc(sizeof(StackNode));
tmp->data = e;
tmp->next = S->top;
S->top = tmp;
S->count++;
return true;
}

出栈操作:

bool Pop(LinkStack *S, Elemtype *e)
{
LinkStack p;
*e = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
S->count--:
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: