栈:顺序栈和链式栈
2013-11-03 14:32
148 查看
前面已经介绍了“链表”,包括顺序链表和链式链表。链表和栈都属于线性表,只是栈是一种特殊的线性表,其“只能够从一端(栈顶)进出”,必须遵循“先进后出”的原则。下面,我们简要学习一下顺序栈和链式栈。
(1)顺序栈
与顺序存储的链表一样,顺序栈也是采用“数组”来存储。其数据结构如下:
这里我们看出,栈和链表的数据结构几乎一模一样,只是里面的成员含义不同而已。在顺序链表里面,定义的是一个长度length,表示所能够存储的最大数据的个数,这个值是不能变化的;而顺序栈中定义的是栈顶元素的下标,这个值可以变化。
对于栈的操作来说,最重要的是“入栈”和“出栈”。这两个操作都必须遵循“FILO”的原则,其具体实现如下:
从上面的知识中,可以知道,顺序栈的操作很方便,但其最大的不足在于,必须事先确定数据存储的最大空间。这里,我们扩展一下知识,下面介绍一下如何做到两个顺序栈共享数据空间。这个方法的基本思想为:数组空间有两个端点,两个栈有两个栈底;让一个栈的栈底位于数组的起始端(下标为0处),让另一个栈的栈底位于数组的末端(下标为N-1处);如果要向栈里面添加元素,那么使栈顶向数组中间移动即可。
数据结构如下:
入栈操作:
(2)链式栈
链式存储的栈就不会存在“栈满”的现象。因此,在进行入栈、出栈的时候,就不用再判断是否满栈了。在对链式栈进行操作时,始终要把握一点:首先看到的是整个栈,而不每一个结点;对于整个栈,只有两个指标——栈顶指针(top)和栈元素个数(count);这样,我们就能够通过栈顶指针(top)来取到栈顶的一个结点,从而获取其中的数据data,并可以创建指针,移动指针位置,遍历栈中的各个元素。也就是说,我们必须“从栈(top、count),再到结点(data、next)”。
其数据解结构可以定义为:
入栈操作:
出栈操作:
(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; }
相关文章推荐
- 栈:顺序栈和链式栈
- Java栈的实现(顺序栈、链式栈)及栈的应用
- C++ —— 数据结构之 顺序栈,链式栈?
- 数据结构学习笔记(6.顺序栈及链式栈)
- 数据结构笔记之用C++实现顺序栈和链式栈
- 数据结构--顺序栈和链式栈
- 对栈的实现(顺序栈和链式栈)C语言
- 数据结构课设--栈(顺序栈,链式栈)
- 数据结构之栈(顺序栈和链式栈)
- 【数据结构】C语言实现顺序栈和链式栈
- 栈的实现 -- 顺序栈和链式栈(C++描述)
- 数据结构与算法分析(c++版) #8 顺序栈和链式栈
- 数据结构--顺序栈和链式栈
- 简单的自定义实现Stack模板(顺序栈以及链式栈没有迭代器和销毁)
- 完成顺序栈,,链式栈的基本操作
- 数据结构--链式栈、顺序栈的基本实现与简单应用:进制转换
- 顺序栈和链式栈的结构及其基本操作(置空,获取栈顶元素,入栈,出栈)
- C#简单实现顺序栈与链式栈
- 数据结构——栈、顺序栈、双栈共享同一栈空间、链式栈
- 顺序栈和链式栈