文章目录
- 栈:
- 顺序栈的实现及操作:
- 1.定义一个栈
- 2.构造一个空栈
- 3.取栈顶元素
- 4.插入元素e
- 5.删除栈顶元素,返回其值
- 6.清空栈,销毁栈
- 栈的操作实例及代码:
栈:
从数据结构上来看,栈也是线性表,但是是操作受限的线性表。
栈是限定仅在表尾进行插入或删除操作的线性表。
对栈来说,表尾端称为栈顶,表头端称为栈底。
栈是后进先出的线性表。
栈的基本操作:在栈顶插入删除,初始化,判空,取栈顶元素等
栈也有两种存储方法,一种是顺序栈,用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。另一种是链栈。这里先整理顺序栈。
顺序栈的实现及操作:
1.定义一个栈
顺序栈的定义完全可以用顺序表的定义,不过这里由于经常要用到栈顶,所以就增加一个top指针,指向栈顶元素的下一个位置。由于当前已存的元素个数length可以由栈顶指针减栈底指针求出,所以,这里就省去length,只保留一个初始化定义时给定的最大存储元素个数stacksize,当使用栈时空间不够,可以再进行扩大。
top指针方便之处,就在于,插入的时候插到top指向的位置上,然后top指针自增。出栈的时候把top指针自减,然后把top指针指向位置的元素取出即可。
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct
{SElemType_Sq *base; SElemType_Sq *top; int stacksize;
}SqStack;
2.构造一个空栈
base称为栈底指针,top称为栈顶指针。构造空栈,top指针和base指针指向同一位置,此时栈里面没有元素(length=0)。其他的和构造一个空顺序表一样。
Status InitStack_Sq(SqStack &S)
{S.base = (SElemType_Sq *)malloc(STACK_INIT_SIZE*sizeof(SElemType_Sq));if(!S.base)exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;
}
3.取栈顶元素
这里取栈顶元素,我们先判断栈是否为空,如果不为空,取栈顶元素。栈顶元素再top指针的上一个位置,也就是S.top - 1(这里可以类比数组,a+1也就是指向a[1]的指针),那么取出的话把地址的值给e即可。注意这里仅仅是取出,不能改变栈顶指针,不能S.top–。
Status GetTop_Sq(SqStack S, SElemType_Sq &e)
{if(S.top==S.base)return ERROR;e = *(S.top - 1); return OK;
}
4.插入元素e
之前说了,S.top-S.base就是length当前已存的元素个数,那么如果length=最大存储元素个数stacksize,那么再插入元素的时候就空间不够了,所以这里需要再增加一段新的空间,能够再多存STACKINCREMENT个元素。弄完之后我们的top指针应该指向栈顶元素的下一个位置,此时已经有stacksize个元素了,也就是说,top指针指向S.base + S.stacksize这个位置。(不理解可以类比数组a+stacksize就是&a[stacksize],而a时下标为0开始存元素的,也就是说现在a+stacksize指向的时第stacksize+1个元素的位置)
然后修改完top指针后,stacksize也更新为S.stacksize + STACKINCREMENT。
此时我们先把e赋值到top指针指向的位置,然后top指针指向栈顶元素的下一个位置,自己加一即可。
Status Push_Sq(SqStack &S, SElemType_Sq e)
{if(S.top-S.base>=S.stacksize) {S.base = (SElemType_Sq *)realloc(S.base, (S.stacksize+STACKINCREMENT)*sizeof(SElemType_Sq));if(!S.base)exit(OVERFLOW); S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top = e; S.top++;return OK;
}
5.删除栈顶元素,返回其值
出栈的时候把top指针自减,然后把top指针指向位置的元素取出即可。
Status Pop_Sq(SqStack &S, SElemType_Sq &e)
{if(S.top==S.base)return ERROR;S.top--; e = *(S.top);return OK;
}
6.清空栈,销毁栈
清空栈,意味着top指针和base指针指向同一位置。
但是销毁栈,top指针和base指针指向null而且stacksize等于0。
Status DestroyStack_Sq(SqStack &S)
{S.base = NULL;S.top = NULL;S.stacksize = 0;return OK;
} Status ClearStack_Sq(SqStack &S)
{S.top = S.base;return OK;
}
栈的操作实例及代码:
代码:
#include<cstdio>
#include<cstdlib>#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10 #define OK 1
#define ERROR 0
#define OVERFLOW -2
#define UNDERFLOW -3
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int SElemType_Sq;typedef struct
{SElemType_Sq *base; SElemType_Sq *top; int stacksize;
}SqStack;Status InitStack_Sq(SqStack &S)
{S.base = (SElemType_Sq *)malloc(STACK_INIT_SIZE*sizeof(SElemType_Sq));if(!S.base)exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;
} Status GetTop_Sq(SqStack S, SElemType_Sq &e)
{if(S.top==S.base)return ERROR;e = *(S.top - 1); return OK;} Status Push_Sq(SqStack &S, SElemType_Sq e)
{if(S.top-S.base>=S.stacksize) {S.base = (SElemType_Sq *)realloc(S.base, (S.stacksize+STACKINCREMENT)*sizeof(SElemType_Sq));if(!S.base)exit(OVERFLOW); S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top = e; S.top++;return OK;
} Status Pop_Sq(SqStack &S, SElemType_Sq &e)
{if(S.top==S.base)return ERROR;S.top--; e = *S.top;return OK;
}
void PrintElem(SElemType_Sq e)
{printf("%d ", e);
}
Status StackTraverse_Sq(SqStack S, void(Visit)(SElemType_Sq))
{ SElemType_Sq *p = S.base;while(p<S.top)Visit(*p++);printf("\n");return OK;
}
Status StackEmpty_Sq(SqStack S)
{if(S.top==S.base)return TRUE;elsereturn FALSE;
} int main(){SqStack S;int i;SElemType_Sq e;printf("初始化顺序栈 S ...\n"); InitStack_Sq(S);printf("\n");StackEmpty_Sq(S) ? printf(" S 为空!!\n") : printf(" S 不为空!\n");printf("\n");for(i=1; i<=6; i++) {printf("将 \"%2d\" 压入栈 S \n", 2*i); Push_Sq(S, 2*i);}printf("\n");printf(" S 中的元素为:S = "); StackTraverse_Sq(S, PrintElem);printf("\n");Pop_Sq(S, e);printf("栈顶元素 \"%d\" 出栈...\n", e);printf(" S 中的元素为:S = "); StackTraverse_Sq(S, PrintElem);printf("\n");GetTop_Sq(S, e);printf("栈顶元素的值为 \"%d\" \n", e);printf("\n");}
运行结果:
初始化顺序栈 S …
S 为空!!
将 " 2" 压入栈 S
将 " 4" 压入栈 S
将 " 6" 压入栈 S
将 " 8" 压入栈 S
将 “10” 压入栈 S
将 “12” 压入栈 S
S 中的元素为:S = 2 4 6 8 10 12
栈顶元素 “12” 出栈…
S 中的元素为:S = 2 4 6 8 10
栈顶元素的值为 “10”