/**
* 实验题目:
* 求解栈元素排序问题
* 实验目的:
* 掌握栈应用的算法设计
* 实验内容:
* 按升序对一个字符栈进行排序,即最小元素位于栈顶。
* 最多只能使用一个额外的栈存放临时数据。
* 并输出栈排序过程。
*/
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
#define MAX_SIZE 100
typedef char ElemType;
typedef struct
{
ElemType data[MAX_SIZE];
int top; //栈顶指针
}SeqStack; //声明顺序栈类型
/*----------------------初始化顺序栈------------------------*/
static void init_stack(SeqStack *&s) // 指针的引用
{
s = (SeqStack *)malloc(sizeof(SeqStack));
s->top = -1;
}
/*----------------------销毁顺序栈------------------------*/
static void destroy_stack(SeqStack *&s)
{
free(s);
}
/*----------------------判断栈空否------------------------*/
static bool stack_empty(SeqStack *s)
{
return (s->top == -1);
}
/*----------------------进栈------------------------*/
static bool push(SeqStack *&s, ElemType e)
{
if(s->top == (MAX_SIZE - 1)) // 栈满的情况,栈上溢出
return false;
s->top++;
s->data[s->top] = e;
return true;
}
/*----------------------出栈------------------------*/
static bool pop(SeqStack *&s, ElemType &e) // 指针的引用
{
if(s->top == -1) // 栈为空的情况,即栈下溢出
return false;
e = s->data[s->top];
s->top--;
return true;
}
/*----------------------取栈顶元素------------------------*/
static bool get_top(SeqStack *s, ElemType &e)
{
if(s->top == -1) // 栈为空的情况,即栈下溢出
return false;
e = s->data[s->top];
return true;
}
/*----------------------对栈中的元素排序------------------------*/
static void stack_sort(SeqStack *&st);
int main(int argc, char *argv[])
{
ElemType e;
SeqStack *s;
init_stack(s);
printf("(1)依次进栈元素1,3,4,2\n");
push(s, '1');
push(s, '3');
push(s, '4');
push(s, '2');
printf("(2)栈s排序过程:\n");
stack_sort(s);
printf("(3)栈s排序完毕\n");
printf("(4)s的出栈序列:");
while(!stack_empty(s))
{
pop(s, e);
printf("%c ", e);
}
printf("\n");
destroy_stack(s);
return 0;
}
/**
* 功能:对栈st中元素排序
* @param st:要排序的栈
* 思路:
* 采用一个额外的栈tmpst存放临时数据。
* 处理st栈的某个栈顶元素e,出栈元素e,将其存放在tmpst中。若临时栈tmpst为空,直接
* 将e进入tmpst中;若tmpst栈不空,将它的元素退栈(放入st栈中)直到tmpst栈顶元素小于e,再
* 将tmp进入到tmpst中,进行这样的过程直到st为空,而tmpst中元素从栈底到栈顶是递增的。再
* 将tmpst中所有元素退栈并进栈到st中。
*/
static void stack_sort(SeqStack *&st)
{
SeqStack *tmpst; // 临时栈
ElemType e, e1;
init_stack(tmpst); // 初始化临时栈
while(!stack_empty(st)) // st栈不空循环
{
pop(st, e); // 出栈元素e
printf(" st:出栈%c=> ", e);
while(!stack_empty(tmpst)) // tmpst栈不空循环
{
get_top(tmpst, e1); // 取栈顶元素e1
printf("tmpst:取栈顶元素%c", e1);
if(e1 > e)
{
printf("因%c>%c ", e1, e);
printf("tmpst:退栈%c ", e1);
pop(tmpst, e1);
printf("s:进栈%c ", e1);
push(st, e1);
}
else
{
printf("因%c<%c,退出循环", e1, e);
break;
}
}
push(tmpst, e);
printf("tmpst:进栈%c\n", e);
}
while(!stack_empty(tmpst))
{
pop(tmpst, e);
push(st, e);
}
destroy_stack(tmpst); // 销毁临时栈
}
测试结果:
(1)依次进栈元素1,3,4,2
(2)栈s排序过程:
st:出栈2=> tmpst:进栈2
st:出栈4=> tmpst:取栈顶元素2因2<4,退出循环tmpst:进栈4
st:出栈3=> tmpst:取栈顶元素4因4>3 tmpst:退栈4 s:进栈4 tmpst:取栈顶元素2因2<3,退出循环tmpst:进栈3
st:出栈4=> tmpst:取栈顶元素3因3<4,退出循环tmpst:进栈4
st:出栈1=> tmpst:取栈顶元素4因4>1 tmpst:退栈4 s:进栈4 tmpst:取栈顶元素3因3>1 tmpst:退栈3 s:进栈3 tmpst:取栈顶元素2因2>1 tmpst:退栈2 s:进栈2 tmpst:进栈1
st:出栈2=> tmpst:取栈顶元素1因1<2,退出循环tmpst:进栈2
st:出栈3=> tmpst:取栈顶元素2因2<3,退出循环tmpst:进栈3
st:出栈4=> tmpst:取栈顶元素3因3<4,退出循环tmpst:进栈4
(3)栈s排序完毕
(4)s的出栈序列:1 2 3 4