顺序栈操作
- 定义
- 结构体
- 顺序栈的基本操作
- 创建栈
- 判栈空
- 压栈
- 弹栈
- 读栈
- 置空栈
- 求栈长度
- 顺序栈应用
1.定义
栈(stack)是一种特殊的线性表.栈是限定结点插入和删除只能在同一端进行的线性表.
栈犹如一个一端开口一端封闭的容器.可插入和删除的一端称为栈顶,另一端称为栈底.
”栈顶指针”:指示最后插入栈中的结点位置,处于栈顶位置的结点称为栈顶结点.”栈底指针”:指示栈底位置,它始终指向最先插入的结点的下面位置.
不含任何结点的栈称为”空栈”.栈为空时,栈顶指针和栈底指针重合.
栈的插入形象地称为”压栈”.删除称为弹栈.
栈的重要特点,最后压入的结点最先弹出,最先压入的结点只能最后弹出.因此,栈又称为后进先出表,或称LIFO表(Last In First Out).
2.结构体
在StackCs.c
# define DT char
# define M 100
typedef struct {
DT data[M];
int top;
}SEQSTACK;
顺序存储结构存储的栈称为”顺序栈”,和顺序表一样,用一个一维数组存储.栈底是:下标为0的数组元素处,也可以设置为另一端.栈顶指针是数组元素的下标,始终指向最后插入的那个元素.这里的指针不是指针类型,而是一个整数.
data[M]是一个一维数组,是栈体,top是栈顶指针.栈底固定在数组的低下标端,所以无需设置栈底指针.当top=0时,栈为空.所以约定的是data[0]闲置不用,即:栈本身的数据是从data[1]开始存储的.
3.顺序表操作
3.1创建栈
创建一个新栈S,且为空栈,并返回S
在StackControl.h写出方法声明
/*
创建空栈
*/
SEQSTACK createEmptyStack();
在StackControl.c中实现此方法
#include "StackControl.h"
/*
创建空栈
*/
SEQSTACK createEmptyStack(){
SEQSTACK S;
S.top=0;
return S;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
// 创建空栈和判空栈
printf("创建空栈和判空栈\n");
SEQSTACK S=createEmptyStack();
int i=isEmptyStack(S);
if(i==1){
printf("S是空栈\n");
}else{
printf("S不是空栈");
}
printf("\n");
}
打印结果:
创建空栈和判空栈
S是空栈
3.2判栈空
判断一个栈是否为空栈,那么就是栈顶指针是否为0,即:栈顶指针和栈底指针相等
判断指定栈是否为空栈,若为空则返回1,否则返回0
在StackControl.h写出方法声明
/*
判栈空
*/
int isEmptyStack(SEQSTACK S){
if(S.top==0){
return 1;
}
return 0;
}
在StackControl.c中实现此方法
#include "StackControl.h"
int isEmptyStack(SEQSTACK S){
if(S.top==0){
return 1;
}
return 0;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
// 创建空栈和判空栈
printf("创建空栈和判空栈\n");
SEQSTACK S=createEmptyStack();
int i=isEmptyStack(S);
if(i==1){
printf("S是空栈\n");
}else{
printf("S不是空栈");
}
printf("\n");
}
打印结果:
创建空栈和判空栈
S是空栈
3.3压栈
将数据添加到栈顶位置.
给定指定结点数据x,向指定栈S插入x,并为栈顶结点
在StackControl.h写出方法声明
/*
压栈
*/
SEQSTACK pussStack(SEQSTACK S,DT value);
/*
显示栈数据
*/
void printfStack(SEQSTACK S);
在StackControl.c中实现此方法
SEQSTACK pussStack(SEQSTACK S,DT value){
//1.判断是否会上溢
if(S.top+1>=M){
printf("overflow puss failure\n");
}else{
//2.移动顶指针
S.top++;
//3.进行压栈数据
S.data[S.top]=value;
printf("puss success!\n");
}
return S;
}
void printfStack(SEQSTACK S){
printf("stack={");
printf("{");
int index=0;
for(int i=1;i<=S.top;i++){
if(index==0){
printf("%c",S.data[i]);
index=1;
}else{
printf(",%c",S.data[i]);
}
}
printf("},top=%d",S.top);
printf("}\n");
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
//压栈
printf("压栈\n");
SEQSTACK pStack={{'0','a','b'},2};
printfStack(pStack);
pStack=pussStack(pStack, 'c');
printfStack(pStack);
printf("\n");
}
打印结果:
压栈
stack={{a,b},top=2}
puss success!
stack={{a,b,c},top=3}
3.4弹栈
从指定栈S中删除栈顶结点
在StackControl.h写出方法声明
/*
弹栈
*/
SEQSTACK popStack(SEQSTACK S);
在StackControl.c中实现此方法
SEQSTACK popStack(SEQSTACK S){
//1.判断是否为空栈
if(S.top==0){
printf("S is Empty Stack,pop stack failure!\n");
}else{
//2.顶指针向下移动一位
S.top--;
//3.将弹出的结点职位空
DT d;
S.data[S.top+1]=d;
printf("pop success!\n");
}
return S;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
//弹栈
printf("弹栈\n");
SEQSTACK poStack={{'0','a','b','c','d','e'},5};
printfStack(poStack);
poStack=popStack(poStack);
printfStack(poStack);
printf("\n");
}
打印结果:
弹栈
stack={{a,b,c,d,e},top=5}
pop success!
stack={{a,b,c,d},top=4}
3.5读栈
读出指栈S的栈顶结点数据,并返回结点数据
在StackControl.h写出方法声明
/*
读栈
*/
DT getStack(SEQSTACK S);
在StackControl.c中实现此方法
DT getStack(SEQSTACK S){
DT t;
//1.判断栈是否为空栈
if(S.top==0){
printf("stack is empty,get stack failure\n");
}else{
t=S.data[S.top];
printf("get stack success!\n");
}
return t;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
//读栈
printf("读栈\n");
SEQSTACK gStack={{'0','a','b','c','d','e'},5};
printfStack(gStack);
DT t=getStack(gStack);
printf("读取的数据是:%c\n",t);
printf("\n");
}
打印结果:
读栈
stack={{a,b,c,d,e},top=5}
get stack success!
读取的数据是:e
3.6置空栈
置指定栈S为空栈,即删除栈中所有结点
在StackControl.h写出方法声明
/*
置空栈
*/
SEQSTACK setEmptyStack(SEQSTACK S);
在StackControl.c中实现此方法
SEQSTACK setEmptyStack(SEQSTACK S){
if(S.top==0){
return S;
}
//1.循环执行弹栈
do{
//栈顶指针向下移动
S.top--;
}while(S.top>0);
printf("置栈空success!\n");
return S;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
//置空栈
printf("置空栈\n");
SEQSTACK setStack={{'0','a','b','c','d','e'},5};
printfStack(setStack);
setStack=setEmptyStack(setStack);
int isEmpty=isEmptyStack(setStack);
if(isEmpty==1){
printf("S是空栈\n");
}else{
printf("S不是空栈");
}
printf("\n");
}
打印结果:
置空栈
stack={{a,b,c,d,e},top=5}
置栈空success!
S是空栈
3.7求栈的长度
计算栈中结点数
在StackControl.h写出方法声明
/*
求栈长度
*/
int getLengthStack(SEQSTACK S);
在StackControl.c中实现此方法
int getLengthStack(SEQSTACK S){
//1.判断是否为空栈,则长度是0
if(S.top==0){
return 0;
}
//栈顶指针是数据的下表,那么长度就是S.top
return S.top;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
//求栈的长度
printf("求栈长度\n");
SEQSTACK lenStack={{'0','a','b','c','d','e'},5};
int length=getLengthStack(lenStack);
printf("length=%d",length);
printf("\n");
}
打印结果:
求栈长度
length=5
顺序栈应用
十进制转换为二进制
在StackControl.h写出方法声明
/*
十进制转换为二进制
*/
void doto(int n);
在StackControl.c中实现此方法
void doto(int n){
SEQSTACK NS;
int x=0;
printf("Conversed to Binary %d=",n);
//1.创建一个空栈
NS=createEmptyStack();
if(n==0){
//2.压栈,第一个数据data[0]不参与操作,栈底指针
NS=pussStack(NS, 0);
}
//3.开始计算转换,知道余数为1
while (n) {
//3.1将n/2的余数压入栈中
NS=pussStack(NS, n%2);
//3.2把商赋给n
n=(n-n%2)/2;
}
//4.进行读栈
while (!isEmptyStack(NS)) {
//读栈
x=getStack(NS);
printf("%d",x);
//弹栈
NS=popStack(NS);
}
printf("\n");
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "StackControl.h"
int main(int argc, const char * argv[]) {
int number=45;
//十进制数据转化二进制
doto(number);
}
打印结果:
Conversed to Binary 45=101101
这是顺序栈基本操作,请大家指点,有好的建议请大家指出,有好的书籍,还往大家推荐!