第三章 栈和队列
一 栈
1 定义
栈是限定仅在表头进行插入和删除操作的线性表。
2 特点
先进后出。
3 实践
1 实现对用户输入的10进制数转化成其他进制并输出(十进制转八进制)
#define STACKSIZE 100
#define JIA_STACKSIZE 10
typedef int Status;
typedef int SElemtype;
typedef struct{
SElemtype *base; //栈底
SElemtype *top; //栈顶
int stacksize; //栈当前的存储空间
}SStack;
int main()
{
int N ;
printf("请输入一个十进制整数:");
scanf("%d",&N);
convert(N);
system("pause");
return 0;
}
//初始化
Status InitStack(SStack &S)
{
S.base=(SElemtype *)malloc(STACKSIZE*sizeof(SElemtype)); //申请空间
if(!S.base) return 0; //分配失败
S.top=S.base;
S.stacksize=STACKSIZE;
return 1;
}
//进栈(插入)
Status Push(SStack &S,SElemtype e)
{
if(S.top-S.base>=S.stacksize) //判满
{
S.base=(SElemtype*)realloc(S.base,(S.stacksize+JIA_STACKSIZE)*sizeof(SElemtype));//分配空间
if(!S.base) return 0; //分配失败
S.top=S.base+S.stacksize;
S.stacksize+=JIA_STACKSIZE;
}
*S.top=e; //插入
S.top++;
return 1;
}
//取栈顶元素
Status Getop(SStack S,SElemtype &e)
{
if(S.top==S.base) return 0;//判空
e=*(S.top-1); //取元素
return 1;
}
//出栈(删除)
Status Pop(SStack &S, SElemtype &e)
{
if(S.top==S.base) return 0; //判空
S.top--;
e=*S.top;//取出栈顶元素元素
return 1;
}
void convert(int N)//实现将十进制数n转换成8进制数字并输出
{
SStack S;
InitStack(S);
int e;
while(N)
{
Push(S,N%8);
N/=8;
}
printf("转换的八进制数为:");
while(S.top!=S.base)
{
Pop(S,e);
printf("%d",e);
}
}
2 计算用户输入的简单表达式的值:例如(5+2)*3 (输入的是字符,只限于十以内的运算)
typedef int SElemtype;
typedef int Status;
typedef struct //定义栈
{
SElemtype *base;
SElemtype *top;
int stacksize;
}Sqstack;
int main()
{
char t;
printf("请输入算术表达式,并以#结束\n");
t=Evaluate();
printf("运算结果是:%c",t);
return 0;
}
Status InitStack(Sqstack &S)//初始化(数)
{
S.base=(SElemtype *)malloc(100 * sizeof(SElemtype));//申请空间
if(!S.base) return 0;
S.top=S.base;
S.stacksize=100;
return 0;
}
Status InitStack(Sqstack &S)//初始化(数)
{
S.base=(SElemtype *)malloc(100 * sizeof(SElemtype));//申请空间
if(!S.base) return 0;
S.top=S.base;
S.stacksize=100;
return 0;
}
Status Push(Sqstack &S,SElemtype e)//进栈
{
if(S.top-S.base>=S.stacksize) //判满
{
S.base=(SElemtype *)realloc(S.base,(S.stacksize+20)*sizeof(SElemtype));
if(!S.base) return 0;
S.top = S.base + S.stacksize;
S.stacksize+=20;
}
*S.top++=e;
return 0;
}
Status Pop(Sqstack &S,SElemtype &e)//出栈
{
if(S.top==S.base) return 0;
e=*--S.top;
return 0;
}
Status Gettop(Sqstack S)//取栈顶元素
{
SElemtype e;
if(S.top==S.base) return 0;
e=*(S.top-1);
return e;
}
Status Evaluate()//表达式求值
{
Sqstack OPTR,OPND;
SElemtype C,theta,x,a,b;
InitStack(OPTR);
InitStack(OPND);
Push(OPTR,'#');
C=getchar();
while(C!='#'||Gettop(OPTR)!='#')
{
if(C>='0'&&C<='9')
{
Push(OPND,C);
C=getchar();
} //if
else
{
switch(Precede((Gettop(OPTR)),C))
{
case'<':
Push(OPTR,C);C=getchar();
break;
case'=':
Pop(OPTR,x);C=getchar();
break;
case'>':
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,(Operate(a,theta,b)));
break;
case' ':
printf("输入的多项式不正确,请重新输入");
break;
} //switch
}
} //while
return Gettop(OPND);
}
Status Precede(SElemtype a,SElemtype b)//优先级函数
{
int t,p;
SElemtype code[7][7]={'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=',' ',
'>','>','>','>',' ','>','>',
'<','<','<','<','<',' ','='};
switch(a)
{
case '+': t=0; break;
case '-': t=1; break;
case '*': t=2; break;
case '/': t=3; break;
case '(': t=4; break;
case ')': t=5; break;
case '#': t=6; break;
}//switch
switch(b)
{
case '+': p=0; break;
case '-': p=1; break;
case '*': p=2; break;
case '/': p=3; break;
case '(': p=4; break;
case ')': p=5; break;
case '#': p=6; break;
}//switch
return code[t][p];
}
Status Operate(SElemtype a,SElemtype c,SElemtype b)//运算函数
{
a=a-48;
b=b-48;
switch(c)
{
case '+': return a+b+48;
case '-': return a-b+48;
case '*': return a*b+48;
case '/':
if(b!=0) return a/b+48;
else
{
printf("除数不能为0!\n");
return 0;
}
}//switch
return 0;
}
二 队列
1 定义
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
2 特点
先进先出。