棧和隊列ADT -數據結構(C語言實現)


數據結構與算法分析

棧模型

  • 限制插入和刪除只能在表的末端的表
  • 表的末端叫做棧頂(top)
  • 支持Push進棧和Pop入棧操作
  • //LIFO后進先出表

棧的實現

鏈表實現

類型聲明

struct Node ;
typedef struct Node *PtrToNode ;
typedef struct Node Stack

int IsEmpty(Stack S) ;
Stack CreateStack(void) ;
void DisposeStack(Stack S) ;
void MakeEmpty(Stack S) ;
void Push(ElementType X,Stack S) ;
ElementType Top(Stack S) ;
void Pop(Stack s) ;

struct Node
{
    ElementType Element ;
    PtrToNode Next ;
}

檢測是否為空棧

void IsEmpty(Stack S)
{
    return S->Next == NULL ;
}

創建空棧

Stack CreateStack(void)
{
    Stack S ;
    S = malloc(sizeof(struct Node)) ;
    if(S == NULL)
    {
       FatalError("內存不足") ;
    }
    S->Next = NULL ;
    MakeEmpty(S) ;
    return S ;
}

void MakeEmpty(Stack S)
{
    if(S == NULL)
    {
        Error("請先創建一個棧") ;
    }
    else
    {
        while(!IsEmpty(S)
            Pop(S) ;
    }
}

Push進棧

void Push(ElementType X, Stack S)
{
    PtrToNode TmpCell ;
    TmpCell = malloc(sizeof(struct Node)) ;
    if(TmpCell == NULL)
        FaltalError("內存不足") ;
    else
    {
        TmpCell->Element = X ;
        TmpCell->Next = S->Next ;
        S->Next = TmpCell ;
    }
}

返回top棧頂元素

ElementType Top(Stack S)
{
    if(!IsEmpty(S)
        return S->Next->ElementType ; 
    Error("空棧") ;
    return 0 ;
}

Pop出棧

void Pop(Stack S)
{
    PtrToNode FirstCell ;
    FirstCell = S->Next ;
    S->Next = FirstCell->Next ;
    free(FirstCell) ;
}

數組實現

  • 潛在危害:需要提前聲明棧的大小
  • 實現思路:
    1. 棧指針TopOfStack //並不是指針,只是指示下標
    2. 壓棧Stack[TopOfStack] = x TopOfStack++ ;
    3. 出棧,TopOfStack-- ;

棧的聲明

struct StackRecord ;
typedef struct StackRecord *Stack ;

int IsEmpty(Stack S) ;
Stack CreateStack(int MaxElements) ;
void DisposeStack(Stack S) ;
void MakeEmpty(Stack S) ;
void Push(ElementType X,Stack S) ;
ElementType Top(Stack S) ;
void Pop(Stack s) ;

define EmptyTOS(-1) ; //空棧標志 加#
define MinStackSize (5) ;

struct Node
{
    ElementType *Array ;
    int Capacity ;
    int TopOfStack ;
}

棧的創建//數組實現

Stack CreateStack(int MaxElements)
{
    Stack S ;
    
    if(MaxElements < MinStackSize)
        Error("棧過小") ;
    S = malloc(sizeof(struct Node) ;
    if(S == NULL)
        FatalError("內存不足") ;
    S->Array = malloc(sizeof(struct Node) * MaxElements) ;
    if(S->Array = NULL)
        FatalError("內存不足") ;
    S->Capacity = MaxElements ;
    MakeEmpty(S) ;
}

void MakeEmpty(Stack S)
{
    S->TopOfStack = EmptyTOS ;
}

釋放棧函數

void DisposeStack(Stack S)
{
    if(S != NULL)
    {
        free(S->Array) ;
        free(S) ;
    }
}

檢測空棧函數

void IsEmpty(Stack S)
{
    return S->TopOfStack == EmptyTOS ;
}

釋放棧函數

void Dispose(Stack S)
{
    if(S != NULL)
    {
        free(S->Array) ;
        free(S) ;
    }
}

壓棧函數

void Push(ElementType X, Stack S)
{
    if(IsFull(S))
        Error("棧滿了") ;
    else
        S->Array[++S->TopOfStack] = X ;
}

返回棧頂函數

ElementType Top(Stack S)
{
    if(!IsEmpty(S))
        return S->Array[S->TopOfStack]
    Error("空棧") ;
    return 0 ;
}

出棧函數

void Pop(Stack S)
{
    if(IsEmpty(S))
        Error("空棧") ;
    S->TopOfStack-- ;
        
}

棧的應用

  • 平衡符號
    1. 后綴表達式
    2. 中綴表達式->后綴表達式
    3. 函數調用

隊列模型

  • Enqueue入隊 在表的末端插入一個元素
  • Dequeue出隊 返回或者刪除表的開頭的元素
  • FIFO先進先出

隊列的實現

數組實現

注意問題:數組浪費為題

解決:循環數組

隊列的類型聲明

struct QueueRecord ;
typedef struct QueueRecord *Queue ;

int IsEmpty(Queue Q) ;
int IsFull(Queue Q) ;
Stack CreateQueue(int MaxElements) ;
void DisposeQueue Q(Queue Q) ;
void MakeEmpty(Queue Q) ;
void Enqueue(ElementType X,Queue Q) ;
ElementType Front(Queue Q) ;
void Dequeue(Queue Q) ;
ElementType FrontAndQueue(Queue Q) ;

#define MinQueueSize(5) ;

Struct QueueRecord
{
    int capacity ;
    int Front ;
    int Rear ;
    int Size ;
    ElementType *Array ;
}

檢測隊列是否為空和構造空隊列

void IsEmpty(Queue Q)
{
    return Q->Size == 0 ;
}

void MakeEmpty(Queue Q)
{
    Q->Size = 0 ;
    Q->Front = 1 ;
    Q->Rear = 0 ;
}

Eequeue入隊函數

void Enqueue(ElementType X, Queue Q)
{
    if(IsFull(Q)
        Error("隊列已滿") ;
    Q->Size++ ;
    Q->Rear = Succ(Q->Rear,Q) ;
    Q->Array[Q->Rear] = X ;
}

int Succ(int Value, Queue Q)
{
    if(++Value == Q->Capacity)
        Value = 0 ;
    return Value ;
}

Dequeue出隊函數

ElementType Dequeue(Queue Q)
{
    ElementType Tmp ;
    if(Q->Rear < Q->Front)
        Error("隊列為空") ;
    Q->Size++ ;
    Tmp = Q->Array[Q->Front] ;
    Q->Front = Succ(Q->Front,Q) ;
    return Tmp ;
}

總結

  • 棧和隊列都屬於表的一種,只是支持更特殊的操作而已
  • 且用途廣泛


免責聲明!

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



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