栈
栈和队列本质也是线性表,其特殊性在于栈和队列的基本操作时线性表操作的子集,它们是操作受限的线性表,因此,可称为限定性的数据结构。
栈是限定仅在表尾进行插入和删除操作的线性表。把栈的表尾称为栈顶,表头端称为栈底。不含元素的空表称为空栈
栈为后进先出(last in first out)的线性表(简称LIFO结构)。
队列为先进先出(first in first out)的线性表(简称FIFO结构)
插入元素的操作为入栈,删除栈顶元素的操作为出栈。
和线性表类似,栈也有两种存储表示方式:
1)顺序栈:一组地址连续的存储单元存储(主要)
2)链栈:data 、 next
定义:
typedef struct{
SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;
base 为栈底指针,在顺序栈中,它始终指向栈底的位置,若base的值为NULL,则表明栈结构不存在。称top为栈顶指针,其初值指向栈底,即top=base可作为栈空的标记,每当插入新的栈顶元素时,指针top增1,;删除栈顶元素时,指针top减1,,因此,非空栈中的栈顶指针始终在栈顶元素额下一个位置上。
//------ ADT Stack的表示与实现 ------ #define STACK_INIT_SIZE 100; //存储空间的初始分配量 #define STACKINCREMENT 10; //存储空间分配增量 typedef struct{ SElemType *base; //在栈构造之前和销毁之后,base的值为NULL SElemType *top; //栈顶指针 int stacksize; //当前已分配的存储空间,以元素为单位 }SqStack; //------ 基本操作的算法描述(部分) ------ Status InitStack(SqStack &S){ //构造一个空栈 S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S.base) exit(OVERFLOW); //存储分配失败 S.top = S.base; //表示栈空 S.stacksize = STACK_INIT_SIZE; return OK; }//InitStack Status GetTop(SqStack S,SElemType &e){ //若栈不空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR if(S.top == S.base) return ERROR; e = *(S.top - 1); return OK; } //GetTop Status Push(SqStack &S,SElemType e){ //插入元素e为新的栈顶元素 if(S.top - S.base >= S.stacksize){ //栈满,追加存储空间 S.base = (SElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) *sizeof(SElemType)); if(!S.base) exit(OVERFLOW); //存储分配失败 S.top = S.base + S.stacksize; S.stacksize += STACKINCREMENT; } *S.top++ = e; //e加入到栈顶,top指针+1 return OK; } //Push Status Pop(SqStack &S,SElemType &e){ //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR if(S.top == S.base) return ERROR; e = * --S.top; //top指针先减1,取出该位置的元素赋值给e return OK; }//Pop //------ 栈的部分应用 ------ //------数制转换 ------ void conversion(int radix){ //输入任意一个非负十进制,转换为其他进制 InitStack(S); //构造空栈 scanf("%d",&N); while(N){ Push(S,N%radix); N = N/radix; } while(!StackEmpty){ Pop(S,e); printf("%d",e); } } //------实现递归 ------ void hanoi(int n,char x,char y,char z){ //move 定义为 printf("%i.Move disk %i from %c to %c \n",++C,n,x,z); if(n == 1) move(x,1,z); //将编号为1的圆盘从x 移到z else{ hanoi(n-1,x,z,y); //将x上编号为1到n-1的圆盘移到y,z作辅助塔 move(x,n,z); //将编号为n的圆盘从x移到z hanoi(n-1,y,x,z); //将y上编号为1到n-1的圆盘移到z,x作辅助塔 } }