一、什麼是棧?
- 棧是限制在一端進行操作(插入、刪除)的線性表;
- 我們俗稱爲堆棧;
- 只不過是一種特殊的線性表,有順序棧、也有鏈式棧
二、棧的特點
- 具有先進後出的特點,即先進棧的數據後出棧(LIFO);
- 入棧出棧可交替進行;
對於特點1、2經常出面試題目:
一個棧的入棧序列爲ABCDE,則不可能的出棧序列爲? (AB)
A:ECDBA
B:DCEAB
C:DECBA
D:ABCDE
E:EDCBA
解析:A:E先出可以做到,C絕對不能在E先出的情況下比B先出棧;所以A錯;
B:D最先出棧,說明之前進棧順序爲ABCD,出棧時B先出A後出,故B錯
C:C先出棧,所以是A,B,C,D依次入棧,D出棧E入棧,E出棧,CBA依次出棧;
D,E:正確;
3.棧的操作只能在線性表的表尾進行,即是我們所說的棧頂;
4.對於棧的實現一般才用順序結構;
三、棧的實現
typedef int ElemType;
typedef struct
{
ElemType *base;//指向棧底的指針
ElemType *top;//指向棧頂的指針
int StackSize;//棧的當前大小
}sqstack_t;
/*創建一個棧*/
void stack_cread(sqstack_t *q)
{
q->base = (ElemType *)malloc(sizeof(ElemType)*MAX_SIZE);//用malloc函數申請一個(sizeof(ElemType)*MAX_SIZE大小的空間,並用base指向它;
if(!q->base)
{
printf("creat stack failed\n");//爲空,申請失敗;
exit(0);
}
q->top=q->base;//創建時棧爲空,即我們的棧頂指針和棧底指針指向同一個地方;
q->StackSize=MAX_SIZE;//我們申請的棧的大小爲100
}
//入棧操作
void stack_push(sqstack_t *q,ElemType e)
{
if(q->top-q->base>=q->StackSize)
{
q->top=(ElemType *)realloc(q->top,sizeof(ElemType)*(MAX_SIZE+ADD_SIZE));//當棧滿時,我們給它增加空間;
if(!q->top)
{
printf("creat failed\n");
exit(0);
}
q->StackSize+=ADD_SIZE;
}
*(q->top)=e;
q->top++;//當前的棧頂指針指向的空間爲空,就是這個存儲單元沒值,入棧時直接放了該空間,然後指針++,方便下次的入棧操作
}
void stack_pop(sqstack_t *q,ElemType *e)
{
if(q->top==q->base)
{
printf("stack is empty\n");
exit(0);
}
else
*e=*(--(q->top));//因爲當前的棧頂指針指向的空間爲空,就是這個存儲單元沒值,方便入棧,所以出棧要先--;
}
四、棧的應用
1、實現逆波蘭標識法:利用棧的特點;輸入爲數字,就入棧,輸入爲運算符號出棧兩次,根據符號計算結果,然後結果入棧;
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
typedef char ElemType;
//typedef int ElemType;
#define MAX_SIZE 100
#define ADD_SIZE 10
typedef struct
{
ElemType *base;//指向棧底的指針
ElemType *top;//指向棧頂的指針
int StackSize;//棧的當前大小
}sqstack_t;
void stack_cread(sqstack_t *);
void stack_push(sqstack_t *q,ElemType e);
ElemType stack_pop(sqstack_t *q);
int stack_clear(sqstack_t *q);
void stack_show(sqstack_t *q);
int main()
{
char ch;
int i=0;
char arr[10];
double num1,num2,num;
sqstack_t Q;
stack_cread(&Q);
printf("please input the number:");
scanf("%c",&ch);
while(ch!='#')
{
while(isdigit(ch)||ch=='.')//判斷是否爲數字
{
arr[i++]=ch;
arr[i]='\0';
scanf("%c",&ch);
if(ch==' ')
{
num=atoi(arr);//字符串轉爲數值
stack_push(&Q,num);
i=0;
}
}
scanf("%c",&ch);
switch (ch)
{
case '+':num1=stack_pop(&Q);
num2=stack_pop(&Q);
stack_push(&Q,num1+num2);
break;
case '-':num1=stack_pop(&Q);
num2=stack_pop(&Q);
stack_push(&Q,num2-num1);
break;
case '*':num1=stack_pop(&Q);
num2=stack_pop(&Q);
stack_push(&Q,num1*num2);
break;
case '/':num1=stack_pop(&Q);
num2=stack_pop(&Q);
if(num1!=0)
stack_push(&Q,num2/num1);
else
printf("error");
break;
}
}
printf("%f",(float)stack_pop(&Q));
return 0;
}