數據結構——線性結構之棧和隊列


一、棧

(一)定義

棧是只能通過訪問它的一端來實現數據存儲和檢索的一種線性數據結構。對於棧的修改要按照先進后出的原則進行,因此,棧又被稱為后進先出(LIFO)的線性表。

(二)基本運算

  1. 初始化:創建一個空棧。
  2. 判斷棧是否為空:如果棧為空,返回“真”,否則返回“假”。
  3. 入棧:將元素x加入棧頂,並更新棧頂指針。
  4. 出棧:將棧頂元素刪除,並更新棧頂指針。可以返回棧頂元素。
  5. 讀取棧頂元素:返回棧頂元素,但不修改棧頂指針。

(三)存儲結構

  1. 順序存儲:用一組地址連續的存儲單元存儲自棧頂到棧底的數據元素。采用這種存儲結構的棧,稱為順序棧。
  2. 鏈式存儲:用鏈表作為存儲結構的棧,稱為鏈棧。鏈表的頭指針就是棧頂指針。

(四)應用

  1. 表達式求值
  2. 括號匹配
  3. 將遞歸過程轉變為非遞歸過程

(五)順序棧代碼

#define TRUE 1
#define FALSE 0
#define ERROR -1
#define NULL -2
typedef int bool;
typedef int ElementType;

Stack CreateStack();
bool IsFull(Stack S);
bool IsEmpty(Stack S);
bool Push(Stack S, ElementType X);
ElementType Pop(Stack S);

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);
}
 
int 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)--] );
}

(六)鏈棧代碼

#define TRUE 1
#define FALSE 0
#define ERROR -1
#define NULL -2
typedef int bool;
typedef int ElementType;

Stack CreateStack();
bool IsEmpty(Stack S);
bool Push(Stack S, ElementType X);
ElementType Pop(Stack S);

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;
    }
}

 

二、隊列

(一)定義

隊列是只能通過訪問它的一端來實現數據存儲和檢索的一種線性數據結構。對於隊列的修改要按照先進先出的原則進行,因此,隊列又被稱為先進先出(FIFO)的線性表。

(二)基本運算

  1. 初始化:創建一個空的隊列。
  2. 判斷隊列是否為空:如果隊列為空,則返回”真“,否則返回”假“。
  3. 入隊:將元素x加入到隊列的隊尾,並更新隊尾指針。
  4. 出隊:將隊頭元素從隊列中刪除,並更新隊頭指針。
  5. 讀取隊頭元素:返回對頭元素的值,但不更新隊頭指針。

(三)存儲結構

  • 順序存儲:隊列的順序結構又稱為順序隊。

  • 鏈式存儲:隊列的鏈式存儲又稱為鏈隊。

(四)應用

  1. 排隊買 XXX
  2. 醫院的掛號系統

(五)順序隊代碼

#define TRUE 1
#define FALSE 0
#define ERROR -1
#define NULL -2
typedef int bool;
typedef int ElementType;
typedef int Position;

Queue CreateQueue(int MaxSize);
bool IsFull(Queue Q);
bool IsEmpty(Queue Q);
bool AddQ(Queue Q, ElementType X);
ElementType DeleteQ(Queue Q);

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;
}
 
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];
    }
}

(六)鏈隊代碼

#define TRUE 1
#define FALSE 0
#define ERROR -1
#define NULL -2
typedef int bool;
typedef int ElementType;
typedef struct Node *PtrToNode;

Queue CreateQueue(int MaxSize);
bool IsFull(Queue Q);
bool IsEmpty(Queue Q);
bool AddQ(Queue Q, ElementType X);
ElementType DeleteQ(Queue Q);

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;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM