3.2链栈
依然设置头结点top
3.2.1结点类型
typedef struct node
{
ElemType data;//数据域
struct node *next;//指针域
}LinkStackNode, *LinkStack;
3.2.2入栈
int Push(LinkStack top, ElemType x) {
temp=(LinkStackNode *)malloc(sizeof(LinkStackNode));
temp->data=x;
temp->next=top->next;//链入
top->next=temp; //完善链入
return TRUE;
}
3.2.3出栈
int Pop(LinkStack top, ElemType *x) {
temp=top->next;
top->next=temp->next;//这一步相当于删除结点top->next
*x=temp->data;//保留数据
free(temp);
return TRUE;
}
3.2.4应用
3.2.4.1进制转化
//十进制转二进制
void Conversion(int N)
{ Stack S; int x; //S为顺序栈或链栈
InitStack(&S);
while(N)
{ x=N%2; Push(&S, x); N=N/2; }//入栈
while(!IsEmpty(S))
{ Pop(&S,&x); printf(“%d”,x); }//出栈
}
//十进制转K进制
void Conversion(int N,int base)
{ Stack S; int x;
InitStack(&S);
while(N)
{ x=N%base; Push(&S, x); N=N/base; }
while(!IsEmpty(S))
{ Pop(&S,&x);
if(x<10) printf(“%d”,x);
else printf(“%c”,x+55); }//A表示10,ASCII码为65
}
3.2.4.2括号匹配
若读入左括号,入栈
若读入右括号,且与栈顶左括号匹配,栈顶左括号出栈
若输入序列完毕后,栈为空,则完全匹配
3.2.4.3回文字符串
原字符串依次入栈
全部入栈后依次出栈
若出栈字符串与原字符串完全相同
则为回文字符串
3.2.4.4表达式求值
中缀表达式求值
分配两个栈元素分别操作数和运算符
操作数和运算符依次入栈
若将入栈运算符优先级大于等于栈顶运算符
则将栈顶操作数(两个)和运算符进行出栈运算
结果重新入操作数栈
后缀表达式求值
后缀表达式求值步骤(引入一个栈即可):
1.读入表达式一个字符
2.若是操作数,压入栈,转4
3.若是运算符,从栈中弹出2个数,将运算结果再压入栈
4.若表达式输入完毕,栈顶即表达式值;
若表达式未输入完,转1
4+3*5 后缀表达式:435*+
3.2.4.5递归
后调用先返回
每当调用一个函数时,就为它在栈顶分配一个存储区
每当从一个函数退出时,就释放它的存储区
当前正在运行的函数的数据区必在栈顶
3.2.4.5.1汉诺塔问题
要求:
将n个圆盘从A移到C,叠放顺序不变
原则:
每次只能移一个圆盘
不能将大盘压到小盘上
main()
{ int m;
printf("Input number of disks”);
scanf("%d",&m);
printf(”Steps : %3d disks”,m);
hanoi(m,'A','B','C');
}
void hanoi(int n,char x,char y,char z)
{
if(n==1)
move(1,x,z);//n=1时,直接把圆盘从A移到C
else{
hanoi(n-1,x,z,y);//先把上面n-1个圆盘从A移到B
move(n,x,z);//然后将n号盘从A移到C
hanoi(n-1,y,x,z);//再将n-1个盘从B移到C
}
}
即把求解n个圆盘的Hanoi问题转化为求解n-1个圆盘的Hanoi问题,
依次类推,
直至转化成只有一个圆盘的Hanoi问题