運算符號位於兩個運算數中間。eg: abc*+de/-。數組
處理後綴表達式的思想:記住數字,等到掃描到運算符號後進行計算。所以須要一種數據結構,能順序存儲運算數而且倒序輸出——引入堆棧(後進先出LIFO)數據結構
棧的順序存儲結構一般由一個一維數組和一個記錄棧頂元素位置的變量組成。指針
typedef int Position; struct SNode { ElementType *Data; /* 存儲元素的數組 */ Position Top; /* 棧頂指針 */ int MaxSize; /* 堆棧最大容量 */ }; typedef struct SNode *Stack; Stack CreateStack( int MaxSize ) { Stack S = (Stack)malloc(sizeof(struct SNode)); S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType)); S->Top = -1; S->MaxSize = MaxSize; return S; }
bool IsFull( Stack S ) { return (S->Top == S->MaxSize-1); } bool Push( Stack S, ElementType X ) { if ( IsFull(S) ) { printf("堆棧滿"); return false; } else { S->Data[++(S->Top)] = X; return true; } }
bool IsEmpty( Stack S ) { return (S->Top == -1); } ElementType Pop( Stack S ) { if ( IsEmpty(S) ) { printf("堆棧空"); return ERROR; /* ERROR是ElementType的特殊值,標誌錯誤 */ } else return ( S->Data[(S->Top)--] ); }
棧的鏈式存儲結構實際上就是一個單鏈表,叫作連棧。插入和刪除操做只能在鏈棧的棧頂進行。棧頂指針top應該在鏈表的頭上。code
typedef struct SNode *PtrToSNode; struct SNode { ElementType Data; PtrToSNode Next; }; typedef PtrToSNode Stack;
Stack CreateStack( ) { /* 構建一個堆棧的頭結點,返回該結點指針,頭結點不放東西哦 */ Stack S; S = (Stack)malloc(sizeof(struct SNode)); S->Next = NULL; return S; } bool IsEmpty ( Stack S ) { /* 判斷堆棧S是否爲空,如果返回true;不然返回false */ return ( S->Next == NULL ); }
bool Push( Stack S, ElementType X ) { /* 將元素X壓入堆棧S */ PtrToSNode TmpCell; TmpCell = (PtrToSNode)malloc(sizeof(struct SNode)); TmpCell->Data = X; TmpCell->Next = S->Next; S->Next = TmpCell; return true; }
ElementType Pop( Stack S ) { /* 刪除並返回堆棧S的棧頂元素 */ PtrToSNode FirstCell; ElementType TopElem; if( IsEmpty(S) ) { printf("堆棧空"); return ERROR; } else { FirstCell = S->Next; TopElem = FirstCell->Data; S->Next = FirstCell->Next; free(FirstCell); return TopElem; } }
隊列的順序存儲結構一般由一個一維數組和一個記錄隊列頭元素位置的變量front以及一個記錄隊列元素位置的變量rear組成。隊列
typedef int Position; struct QNode { ElementType *Data; /* 存儲元素的數組 */ Position Front, Rear; /* 隊列的頭、尾指針 */ int MaxSize; /* 隊列最大容量 */ }; typedef struct QNode *Queue; Queue CreateQueue( int MaxSize ) { Queue Q = (Queue)malloc(sizeof(struct QNode)); Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType)); Q->Front = Q->Rear = 0; Q->MaxSize = MaxSize; return Q; }
爲了避免浪費空間,引入順環隊列:it
注意:爲了判斷這種隊列的空滿,要麼引入size記錄元素個數,要麼只放n-1個空間。io
bool IsFull( Queue Q ) { return ((Q->Rear+1)%Q->MaxSize == Q->Front); } bool AddQ( Queue Q, ElementType X ) { if ( IsFull(Q) ) { printf("隊列滿"); return false; } else { Q->Rear = (Q->Rear+1)%Q->MaxSize; Q->Data[Q->Rear] = X; return true; } }
bool IsEmpty( Queue Q ) { return (Q->Front == Q->Rear); } ElementType DeleteQ( Queue Q ) { if ( IsEmpty(Q) ) { printf("隊列空"); return ERROR; } else { Q->Front =(Q->Front+1)%Q->MaxSize; return Q->Data[Q->Front]; } }
單向鏈表頭部作插入刪除操做均可以,尾部不能作刪除操做。所以只能頭部作插入尾部作刪除。入門
typedef struct Node *PtrToNode; struct Node { /* 隊列中的結點 */ ElementType Data; PtrToNode Next; }; typedef PtrToNode Position; struct QNode { Position Front, Rear; /* 隊列的頭、尾指針 */ int MaxSize; /* 隊列最大容量 */ }; typedef struct QNode *Queue;
bool IsEmpty( Queue Q ) { return ( Q->Front == NULL); } ElementType DeleteQ( Queue Q ) { Position FrontCell; ElementType FrontElem; if ( IsEmpty(Q) ) { printf("隊列空"); return ERROR; } else { FrontCell = Q->Front; if ( Q->Front == Q->Rear ) /* 若隊列只有一個元素 */ Q->Front = Q->Rear = NULL; /* 刪除後隊列置爲空 */ else Q->Front = Q->Front->Next; FrontElem = FrontCell->Data; free( FrontCell ); /* 釋放被刪除結點空間 */ return FrontElem; } }