1.设一个栈的输入序列为1,2,……n,编写算法判断序列p1,p2……pn是否是一个合理的栈输出序列
解:当输入序列为1,2,3,当输出序列为2,3,1,预期为1进2进2出3进3出1出;
当输出序列为3,1,2,预期为1进3进3出1出2进2出则经过试验发现不合理
当前数据 | 1 | 2 | 3 | ||||
栈顶数据 | - | 1 | 2 | 1 | 3 | 1 | - |
预期输出序列 | 2 | 2 | 3 | 3 | 1 | ||
栈顶与预期输出数据比较 | 1<2 | 2=2 | 1<3 | 3=3 | 1=1 | ||
动作 | 1进 | 2进 | 2出 | 3进栈 | 3出栈 | 1出栈 | 结束 |
当前数据 | 1 | 2 | 3 | |||
栈顶数据 | - | 1 | 2 | 3 | 2 | |
预期输出序列 | 3 | 3 | 3 | 1 | ||
栈顶与预期输出数据比较 | 1<3 | 2<3 | 3=3 | 2>1 | ||
动作 | 1进 | 2进 | 3进 | 3出栈 | 错误 | 结束 |
从第二个表可得到,当预期输出序列数据比当前栈顶元素小时,必然出现了输出不合理。
/**i=1,2,3...作为栈的输入数据序列,p[]作为预期栈的输出序列*/
void Decision(int p[],int n){
SeqStack;InitStack(S);
int i=0,k=0,j;
bool s=true;
do{ //当栈空或栈顶元素<预期输出数据,进栈
if(StackEmpty(S)||GetTop(S)<p[k]) Push(S,++i);
else if(!StackEmpty(S)&&GetTop(S)==p[k]){//栈非空且栈顶元素==预期输出数据,出栈
j=Pop(S);k++;}
else if(GetTop(S)>p[k]){//栈顶元素>预期输出数据,结束
s=false;break;
}
}while(k<n);
for(j=0;j<n;j++) printf("%d",p[j]);
if(s) printf("合理\n");
else printf("不合理\n");
}
2.改写顺序栈的进栈成员函数Push(x),要求当栈满时执行一个stackfull()操作进行溢出处理。
其功能:动态创建一个比原来的栈数组大一倍的新数组,代替原来的栈数组,原来栈数组中的元素占据新数组的前maxSize个位置
解:这个原理当初在集合的学习时思考过。stackfull()是让创建个新的数组,把原来的数组元素复制到前maxSize个位置,再释放原栈数组,用新数组代替原栈数组并修改maxSize。top可不变,它指示的是数组下标
void Push(SeqStack& S,SElemtype x);
void StackFull(SeqStack& S);
void Push(SeqStack& S,SElemtype x){
if(S.top==S.maxSize-1)StackFull(S);//栈满,作溢出处理
S.elem[++S.top]=x; //进栈
}
void StackFull(SeqStack& S){
int i;
SElemtype *temp=(SElemtype)malloc(2*S.maxSize*sizeof(SElemtype));
if(temp==NULL) { printf("存储失败!\n");exit(1);}
for(i=0;i<=S.top;i++) temp[i]=S.elem[i]; //将原栈数据复制到新栈
free(S.elem); //删除原数组
S.maxSize=2*S.maxSize; //数组扩容
S.elem=temp;
}
3.设计有一个元素类型为整型的栈S,设计一个算法,借助另一个栈实现把该栈的所有元素从栈顶按从小到大的次序排列起来。
解:设待排序的栈为S,辅助排序的栈为T。
(1)循环执行从栈顶退出一个整数,置与k。
若栈非空,则从栈T退出所有大于k的元素,再送回S栈;
若栈T已空,或栈T的栈顶元素的值<=k,则把k压入栈T
(2)执行完(1),所有栈T中元素逐个,再压入栈S,结束。
void StackSort(SeqStack& S){
SeqStack T;InitStack(T);
int i,k;
while(!StackEmpty(S)){
k=Pop(s);
while(!StackEmpty(T)&&GetTop(T)>k) Push(S,Pop(T));
Push(T,k);
}
while(!StackEmpty(T))
Push(S,Pop(T));
}
4.设计算法利用队列的运算查找循环队列Q中的最小元素并返回它的位置
解:一般基于比较来寻找最小值。假定队列中队头(设为0号元素)最小,逐一出队再进队,若刚出队元素比最小元素值还小,置此元素为最小元素。当整个队列元素都查看完成,最小元素的位置就记录下来了。
int findMin(CircQueue &Q){
int i,k,m=0,n=QueueSize(Q); //求队列元素个数
Datatypep min=DeQueue(Q); EnQueue(Q,min); //最初假定0号最小
for(i=1;i<n;i++){ //循环找最小元素
k=DeQueueu(Q); EnQueue(Q,k);
if(k<min){min=k;m=i;} //m记录最小元素位置,从0开始
}
return m;
}
5.设置优先队列PQueue采用一个一维数组elem[maxsize]作为其存储表示,且要求新元素插入到队列的队尾,删除在队列的队头进行,被删除的队头元素应是队列中具有最高优先级的元素。请设计它的存储结构,给出队空队满条件,并给出进队和出队的算法。
解:优先队列使用一维数组elem[maxsize]作为其存储结构,队头设置在数组0号位置,同时设置计数单元count,记录队列元素个数。因此,数组下标0~count-1的部分存放队列元素。队空条件是count=0,队满的条件是count=maxSize-1;
假设优先级最高的元素值最小,进队运算先将进队元素x存入count所指位置(即队尾),并将count加1,
然后检查队列所有元素,找到值最小的元素,把它交换到数组的0号位置;
出队运算先从0号位置(队头)取出出队元素,再把最后一个元素填补0号元素位置并让count减一,最后顺序检查队列所有元素,找到值最小的元素,把它交换到数组的0号位置。
#define maxsize 20
typedef int DataType
typedef struct{
DataType elem[maxsize];
int count;
}PQueue;
int PQInsert(PQueue& Q,DataType x){
//将新元素x插入到优先级队列的队尾,然后找到值最小的元素并交换到队头
if(Q.count==maxsize) return 0; //队满退出
Q.elem[Q.count]=x; Q.count++; //在队尾插入x
int i,k=0;
for(i=1;i<Q.count;i++) //寻找最小值
if(Q.elem[i]<Q.elem[k]) k=i; //记忆最小值元素下标
if(k!=0){ //交换0号元素和k号元素
DataType tmp=Q.elem[0]; Q.elem[0]=Q.elem[k];
Q.elem[k]=tmp;
}
return 1;
}
DataType PPQRemove(PPQueue& Q){
//退出优先队列的队头元素并由函数返回。要求队列不空
Dataype x=Q.elem[0];Q.count--; //队头元素存入x
Q.elem[0]=Q.elem[Q.count]; //最后元素填补队头元素
int i,k=0;
for(i=1;i<Q.count;i++) //从0到count-1选最小
if(Q.elem[i]<Q.elem[k]) k=i; //k记录最小元素下标
if(k!=0){ //交换Q.elem[0]与Q.elem[k]
DtaType tmp=Q.elem[0];
Q.elem[0]=Q.elem[k];
Q.elem[k]=tmp;
}
return x;
}
6.编写算法实现将一个非负的十进制整数N转为二进制数
解:
int baseTrans(int N){
int i,result=0;
SeqStack S;
InitStack(S);
while(N!=0) {i=N%2; N=N/2; Push(S,i);}
while(!StackEmpty(S)){
i=Pop(S);
result=result*10+i;}
return result;
}