1. 相關結構體定義
1.1 順序棧
typedef struct{
int data[maxSize]; //存放棧中元素
int top; //棧頂指針
}SqlStack; //順序棧類型定義
1.2 鏈棧結點定義
typedef struct LNode{
int data; //數據域
struct LNode *next; //指針域
}LNode; //鏈棧結點定義
1.3 順序隊列
typedef struct{
int data[maxSize];
int front; //隊首指針
int rear; //隊尾指針
}SqQueue; //順序隊列類型定義
1.4 鏈隊定義
/**
隊列頭結點定義
*/
typedef struct QNode{
int data; //數據域
struct QNode *next; //指針域
}QNode; //隊結點類型定義
/**
鏈隊類型定義
*/
typedef struct{
QNode *front; //隊頭指針
QNode *rear; //隊尾指針
}LiQueue; //鏈隊類型定義
2. 順序棧相關操作
- 初始化棧空
void initStack(SqStack &St){
st.top=-1; //只需要將棧頂指針設置爲1
}
- 判斷棧空
/**
棧空返回1,否則返回0
*/
int isEmpty(SqStack st){
if(st.top==-1)
return 1;
else
return 0;
}
- 進棧
int push(SqStack &st,int x){
if(s.top==maxSize-1) //棧滿
return 0;
++(st.top); //先移動指針,再進棧
st.data[st.top]=x;
return 1;
}
- 出棧
int pop(SqStack &st,int &x){
if(st.top==-1) //棧空,不能出棧
return 0;
x=st.data[s.top]; //先取出元素,再移動指針
--(s.top);
return 1;
}
但試題中一般以以下形式居多:
int stack[maxSize]; int top; //即完成棧的定義及初始化
stack[++top]=x; //元素進棧
x=stack[top--]; //元素出棧
3. 鏈棧相關操作
- 鏈棧初始化
void initStack(LNode *&lst){
lst=(LNode*)malloc(sizeof(LNode)); //製造一個頭結點
lst->next=NULL;
}
- 判斷棧空
int isEmpty(LNode *lst){
if(lst->next==NULL)
return 1;
else
return 0;
}
- 進棧
void push(LNode *lst,int x){
LNode *p;
p=(LNode*)malloc(sizeof(LNode)); //爲進棧元素申請結點空間
p->next=NULL; //指針域設爲NULL
/*鏈表的頭插法*/
p->data=x;
p->next=lst->next;
lst->next=p;
}
- 出棧
int pop(LNode *lst,int &x){
LNode *p;
if(lst->next==NULL)
return 0;
/*單鏈表的刪除*/
p=lst->next;
x=p->data;
lst->next=p->next;
free(p);
return 1;
}
4. 順序棧的應用
1. 判斷一個表達式中的括號是否正確配對
/**
表達式存放在expr[]中,字符個數爲n
*/
int match(char expr[],int n){
char stack[maxSize];int top=-1;
for(int i=0;i<n;i++){
if(expr[i]=='(') //遇到(入棧,
stack[++top]='(';
if(expr[i]==')'){
if(top==-1)
return 0;
else //棧不空,則出棧,
--top;
}
}
if(top==-1) //棧空,匹配
return 1;
else
return 0;
}
2. 編寫一個求後綴式的數值的函數
/**
後綴式存儲在expr中,最後一個字符爲"\0",作爲結束符,後綴式中數字只有一位
*/
int op(int a,char opt,int b){
if(opt=='+') return a+b;
if(opt=='-') return a-b;
if(opt=='*') return a*b;
if(opt=='/') {
if(b==0){
return 0;
}
else
return a/b;
}
}
int com(char expr[]){
int stack[maxSize];int top=-1;
int a,b,c;
char opt;
for(int i=0;expr[i]!='\0';i++){
if(expr[i]>='0'&&expr[i]<='9')
stack[++top]=expr[i]-'0';
else{
opt=expr[i]; //取運算符
b=stack[top--]; //取第二個操作數
a=stack[top--]; //取第一個操作數
c=op(a,opt,b);
stack[++top]=c; //運算結果入棧
}
}
return stack[top];
}
5. 順序隊
5.1 循環隊列
兩個狀態:
隊空狀態:qu.rear== qu.front
隊滿狀態:(qu.rear+1)%maxSize==qu.front
兩個操作:
入隊:qu.rear=(qu.rear+1)%maxSize; qu.data[qu.rear]=x;
出隊:qu.front=(qu.front+1)%maxSize; x=qu.data[qu.front];
- 初始化隊列
void initQueue(SqQueue &qu){
qu.front=qu.rear; //隊首和隊尾指針重合,並且指向0
}
- 判斷隊空
int isEmpty(SqQueue qu){
if(qu.front==qu.rear)
return 1;
else
return 0;
}
- 進隊
int enQueue(SqQueue &qu,int x){
if((qu.rear+1)%maxSize==qu.front) //隊滿
return 0;
qu.rear=(qu.rear+1)%maxSize; //隊未滿,先移動指針
qu.data[qu.rear]=x; //再存入元素
return 1;
}
- 出隊
int Dequeue(Squeue &qu,int &x){
if(qu.front==qu.rear) //隊空,不能出隊
return 0;
qu.front=(qu.front+1)%maxSize;
x=qu.data[qu.front]; //取出元素
return 1;
}
5.2 鏈隊
- 兩個狀態
隊空:lqu->rear== NULL或者lqu->front== NULL
- 兩個操作
進隊:lqu->rear->next=p;lqu->rear=p;
出隊:p=lqu->front;lqu->front=p->next;x=p->data;free(p);
- 初始化隊列
void initQueue(LiQueue *&lqu){
lqu=(LiQueue*)malloc(sizeof(LiQueue));
lqu->front=lqu->rear=NULL;
}
- 判斷隊空
int isEmpty(LiQueue *lqu){
if(lqu->rear==NULL||lqu->front==NULL)
return 1;
else
return 0;
}
- 入隊
void enQueue(LiQueue *lqu,int x){
QNode *p;
p=(QNode*)malloc(sizeof(QNode));
p->data=x;
p->next=NULL;
if(lqu->rear==NULL) //隊列空,則新結點是隊首結點,也是隊尾結點
lqu->front=lqu->rear=p;
else
lqu->rear->next=p; //將新結點鏈接到隊尾,rear指向它
lqu->rear=p;
}
- 出隊
int deQueue(LiQueue *lqu,int &x){
QNode *p;
if(lqu->rear==NULL)
return 0;
else
p=lqu->front;
if(lqu->front==lqu->rear) //隊列中只有一個結點時
lqu->front=lqu->rear=NULL;
else
lqu->front=lqu->front->next;
x=p->data;
free(p);
return 1;
}