棧和隊列代碼總結

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. 順序棧相關操作

  1. 初始化棧空
void initStack(SqStack &St){
	st.top=-1;        //只需要將棧頂指針設置爲1
}
  1. 判斷棧空
/**
棧空返回1,否則返回0
*/
int isEmpty(SqStack st){
	if(st.top==-1)
		return 1;
	else 
		return 0;
}
  1. 進棧
int push(SqStack &st,int x){
	if(s.top==maxSize-1)     //棧滿
		return 0;
	++(st.top);              //先移動指針,再進棧
	st.data[st.top]=x;
	return 1;
}
  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. 鏈棧相關操作

  1. 鏈棧初始化
void initStack(LNode *&lst){
	lst=(LNode*)malloc(sizeof(LNode));    //製造一個頭結點
	lst->next=NULL;
}
  1. 判斷棧空
int isEmpty(LNode *lst){
	if(lst->next==NULL)
		return 1;
	else 
		return 0;
}
  1. 進棧
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;
}
  1. 出棧
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);
  1. 初始化隊列
void initQueue(LiQueue *&lqu){
	lqu=(LiQueue*)malloc(sizeof(LiQueue));
	lqu->front=lqu->rear=NULL;
}
  1. 判斷隊空
int isEmpty(LiQueue *lqu){
	if(lqu->rear==NULL||lqu->front==NULL)
		return 1;
	else 
		return 0;
}
  1. 入隊
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;
}
  1. 出隊
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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章