堆棧(Stack):具備必定操做約束的線性表(只在一端(棧頂,Top)作插入、刪除)node
類型名稱: 堆棧(Stack)
數據對象集:一個有0個或多個元素的有窮線性表。
操做集:長度爲MaxSize的堆棧S Stack,堆棧元素item ElementType
一、Stack CreateStack( int MaxSize )
: 生成空堆棧,其最大長度爲MaxSize;
二、int IsFull( Stack S, int MaxSize )
:判斷堆棧S是否已滿;
三、void Push( Stack S, ElementType item )
:將元素item壓入堆棧;
四、int IsEmpty ( Stack S )
:判斷堆棧S是否爲空;
五、ElementType Pop( Stack S )
:刪除並返回棧頂元素;數組
Push 和 Pop 能夠穿插交替進行;
按照操做系列
(1)Push(S,A), Push(S,B),Push((S,C),Pop(S),Pop(S),Pop(S)
堆棧輸出是?函數
CBA設計
(2) 而Push(S,A), Pop(S),Push(S,B),Push((S,C),Pop(S),Pop(S)
堆棧輸出是?3d
ACB指針
棧分爲順序棧和鏈式棧。code
棧的順序存儲結構一般由一個一維數組和一個記錄棧頂元素位置的變量組成。對象
#define MaxSize <儲存數據元素的最大個數> typedef struct SNode *Stack; struct SNode { ElementType Data[MaxSize]; int Top; };
void Push( Stack PtrS, ElementType item ) { if ( PtrS->Top == MaxSize-1 ) { printf("堆棧滿"); return; } else { PtrS->Data[++(PtrS->Top)] = item; return; } }
ElementType Pop( Stack PtrS ) { if ( PtrS->Top == -1 ) { printf("堆棧空"); return ERROR; /* ERROR是ElementType的特殊值,標誌錯誤 */ } else return ( PtrS->Data[(PtrS->Top)--] ); }
棧的鏈式存儲結構實際上就是一個單鏈表,叫作鏈棧。插入和刪除操做只能在鏈棧的棧頂進行。blog
typedef struct SNode *Stack; struct SNode { ElementType Data; struct SNode *Next; } ;
Stack CreateStack() { /* 構建一個堆棧的頭結點,返回指針 */ Stack S; S =(Stack)malloc(sizeof(struct SNode)); S->Next = NULL; return S; }
int IsEmpty(Stack S) { /*判斷堆棧S是否爲空,若爲空函數返回整數1,不然返回0 */ return ( S->Next == NULL ); }
這裏的S並非頭節點,而是指向頭節點隊列
void Push( ElementType item, Stack S) { /* 將元素item壓入堆棧S */ struct SNode *TmpCell; TmpCell=(struct SNode *)malloc(sizeof(struct SNode)); TmpCell->Element = item; TmpCell->Next = S->Next; S->Next = TmpCell; }
ElementType Pop(Stack S) { /* 刪除並返回堆棧S的棧頂元素 */ struct SNode *FirstCell; ElementType TopElem; if( IsEmpty( S ) ) { printf(「堆棧空」); return NULL; } else { FirstCell = S->Next; S->Next = FirstCell->Next; TopElem = FirstCell ->Element; free(FirstCell); return TopElem; } }
隊列(Queue):具備必定操做約束的線性表
類型名稱:隊列(Queue)
數據對象集:一個有0個或多個元素的有窮線性表。
操做集:長度爲MaxSize的隊列Q Queue,隊列元素item ElementType
一、Queue CreatQueue( int MaxSize )
:生成長度爲MaxSize的空隊列;
二、int IsFullQ( Queue Q, int MaxSize )
:判斷隊列Q是否已滿;
三、void AddQ( Queue Q, ElementType item )
: 將數據元素item插入隊列Q中;
四、int IsEmptyQ( Queue Q )
: 判斷隊列Q是否爲空;
五、ElementType DeleteQ( Queue Q )
:將隊頭數據元素從隊列中刪除並返回。
隊列的順序存儲結構一般由一個一維數組和一個記錄隊列頭元素位置的變量front以及一個記錄隊列尾元素位置的變量rear組成。
#define MaxSize <儲存數據元素的最大個數> struct QNode { ElementType Data[ MaxSize ]; int rear; int front; }; typedef struct QNode *Queue;
順序隊列的一個劣勢就是,隨着數據的入隊列和出隊列,front和rear指針會一直向右移動,最終可能沒法再添加新的元素,可是這個時候數組其實還有不少的空間,爲了讓隊列繼續可用,就須要數據搬移。
而爲了不數據搬移,就會把順序存儲結構的隊列設計成循環隊列。
循環隊列的本質就是在入隊列的時候,rear指針會回到數組的前面去。
你也能夠把它的邏輯圖畫成這樣
隊列空:
front==rear
隊列滿:
(rear+1)%maxsize == front
void AddQ( Queue PtrQ, ElementType item) { if ( (PtrQ->rear+1) % MaxSize == PtrQ->front ) { printf("隊列滿"); return; } PtrQ->Data[PtrQ->rear] = item; PtrQ->rear = (PtrQ->rear+1)% MaxSize; }
ElementType DeleteQ ( Queue PtrQ ) { if ( PtrQ->front == PtrQ->rear ) { printf("隊列空"); return ERROR; } else { ElementType x = PtrQ->Data[PtrQ->front]; PtrQ->front = (PtrQ->front+1)% MaxSize; return x; } }
隊列的鏈式存儲結構也能夠用一個單鏈表實現。插入和刪除操做分別在鏈表的兩頭進行。
struct Node { ElementType Data; struct Node *Next; }; struct QNode { /* 鏈隊列結構 */ struct Node *rear; /* 指向隊尾結點 */ struct Node *front; /* 指向隊頭結點 */ }; typedef struct QNode *Queue; Queue PtrQ;
ElementType DeleteQ ( Queue PtrQ ) { struct Node *FrontCell; ElementType FrontElem; if ( PtrQ->front == NULL) { printf("隊列空"); return ERROR; } FrontCell = PtrQ->front; if ( PtrQ->front == PtrQ->rear) /* 若隊列只有一個元素 */ PtrQ->front = PtrQ->rear = NULL; /* 刪除後隊列置爲空 */ else PtrQ->front = PtrQ->front->Next; FrontElem = FrontCell->Data; free( FrontCell ); /* 釋放被刪除結點空間 */ return FrontElem; }
void AddQ( Queue Q, ElementType x) { Node *newnode =(Node*)malloc(sizeof(Node)); newnode->Data = x; newnode->Next = NULL; if ( PtrQ->front == NULL) { //空隊列 Q->front = Q ->rear = newnode; } else{ Q->rear->Next = newnode; Q->rear = newnode; } }