题目描述:对于一个非空栈,请设计一个算法颠倒栈中的元素。
首先我们设计的栈的实现代码是:
/* * 问题描述:栈实现的基本代码。 * @author : xiaoq-ohmygirl * @time : 2012-07-03 **/ #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <math.h> //栈的初始最大容量 #define STACK_MAX_SIZE 100 //栈的容量增量 #define INCREAMENT 10 //状态函数 #define ERROR 0 #define OK 1 #define SOVERFLOW -1 #define YES 1 #define NO 0 typedef int Status,SElemType,ElemType; typedef struct{ SElemType *base; SElemType *top; int stackSize;//当前已经分配的空间,不是指栈中元素个数。 }sqStack; Status InitStack(sqStack &S){ //初始化栈空间,栈为空 S.base = (SElemType *)malloc(STACK_MAX_SIZE * sizeof(ElemType)); if(!S.base){ exit(SOVERFLOW); } S.top = S.base; S.stackSize = STACK_MAX_SIZE; return OK; } //如果栈不空,用e传出栈顶元素并返回OK。否则返回错误。 Status GetTop(sqStack S,SElemType &e){ if(S.top == S.base){ return ERROR; } e = *(S.top - 1); return OK; } /* * Push(S,e)向栈S中压入元素e。需要考虑的情况有: * 1.栈已经满,需要增加空间。如果无法继续增加空间,则退出。 * 2.栈未满。先压入元素,然后修改栈顶指针。 **/ Status Push(sqStack &S,SElemType e){ if((S.top - S.base) >= S.stackSize){ S.base = (ElemType*)realloc(S.base,(S.stackSize + INCREAMENT) * sizeof(ElemType)); if(!S.base){ exit(SOVERFLOW); } S.top = S.base + S.stackSize; S.stackSize += INCREAMENT; } //先压入元素,然后修改指针。弹出时相反 *S.top = e; S.top ++; return OK; } /* * 弹出栈顶元素。需要注意的有: * 1.栈不空。则先修改指针,然后弹出元素并传送给e。 * 2.栈为空时,返回错误。 */ Status Pop(sqStack &S,ElemType &e){ if(S.top == S.base){ return ERROR; } //先修改指针,然后弹出元素。 S.top --; e = *S.top; return OK; } Status isEmpty(sqStack S){ if(S.top == S.base){ return YES; } return NO; }
思路1,也就是最简单的想法,基于栈的后入先出的性质。可以设计另一个辅助栈(栈2),每次栈1pop一个元素,栈2中push相应的元素。
算法如下:
sqStack reverseStack(sqStack S){ sqStack help; InitStack(help); SElemType node; while(!isEmpty(S)){ Pop(S,node); Push(help,node); } return help; } main(){ sqStack S; sqStack tmp; InitStack(S); InitStack(tmp); int rands,rest; printf("入栈:"); for(int i = 0;i < 100;i++){ rands = rand()%1000; Push(S,rands); printf("%d \n",rands); } tmp = reverseStack(S); printf("\n 颠倒栈: "); while(!isEmpty(tmp)){ Pop(tmp,rest); printf("%d \n",rest); } system("pause"); return 0; }
依次进行这个过程。直到栈为空。
如何将元素放入栈底呢?
仔细分析后发现,就是另一个递归的过程。
即:if(栈为空){
那么直接push。此刻元素就是在栈底。
}else{
否则。弹出栈顶元素。将待push元素放入栈底。然后将原栈顶元素push进栈中即可。
}
此思路的完整代码如下:
void addToBottom(sqStack &S,SElemType node){ if(isEmpty(S)){ Push(S,node); }else{ SElemType tmp ; Pop(S,tmp); addToBottom(S,node); Push(S,tmp); } } void reverStack(sqStack &S){ SElemType node; if(!isEmpty(S)){ Pop(S,node); reverStack(S); addToBottom(S,node); } } main(){ sqStack S; InitStack(S); int rands,rest; printf("入栈:"); for(int i = 0;i < 100;i++){ rands = rand()%1000; Push(S,rands); printf("%d \n",rands); } reverStack(S); printf("\n 颠倒栈: "); while(!isEmpty(S)){ Pop(S,rest); printf("%d \n",rest); } system("pause"); return 0; }