1. 假设用I、O表示入栈和出栈操作,栈的初态和终态都为空时合法,设计一个算法判断是否合法
区分:
判断带头节点的栈空:lst->next=NULL
判断不带头节点的栈空: lst=NULL
代码
int judge(char a[],int n) { //n为元素个数
int i;
LiStack *lst;
InitStack(LiStack *&lst); //先初始化栈
for(i=0;i<n;i++){
if(A[i]=='I') push(A[i]); //进栈
else if(A[i]=='O') pop(A[i]); //出栈
else return 0; //其他值无效退出
}
return (lst->next==NULL);
}
//初始化
void InitStack(LiStack *&lst){
lst=(LiStack *)malloc(sizeof(LiStack));
lst->next=NULL;
}
//进栈
void push(LiStack *&lst,ElemType x){
*p=(LiStack *)malloc(sizeof(LiStack)); //开辟新空间
p->data=x;
p->next=lst->next; //插入p节点作为第一个数据节点
lst->next=p;
}
//出栈
void pop(LiStack *&lst,ElemType x){
LiStack *p;
//出栈的第一步一定先判断栈是不是为空
if(lst->next==NULL) return 0;
//第二步p指向头节点后第一个节点
p=lst->next;
x=p->data; //将第一个节点的数据域赋给x
lst->next=p->next; //头节点指针指向第一个节点的后继节点
free(p);
return 1;
}
出栈要点:
第一步一定先判断栈是不是为空
第二步p指向头节点后第一个节点
第三步将第一个节点p的数据域赋给x
2. 有一个带头节点的单链表L,将单链表中的节点逆置(利用链栈)
思路
设计一个不带头节点的链栈,类型和单链表相同,用p指针遍历单链表,将单链表中所有元素进栈,再依次出栈,以尾插法的方式更新单链表
代码
// 链栈逆置
void Reverse(LinkList *&L){
LinkList *p=L->next;*q;
LinkList *lst=NULL; //定义一个不带头节点的链栈
while(p!=NULL){
q=p->next; //用q来标记p此时遍历到哪个位置
p->next=lst; //进栈
lst=p;
p=q;
}
//依次出栈,尾插法进入单链表
q=L; //此时q指向链表的尾节点
while(lst!=NULL){
q->next=lst; //将lst插入q之后
q=lst;
lst=lst->next; //指针后移
}
q->next=NULL; //尾节点next域置为空
}