1. 程式人生 > >鏈棧的表示和實現

鏈棧的表示和實現

//庫函式標頭檔案包含
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

//函式狀態碼定義
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int Status;
typedef int SElemType;

//----------棧的鏈式儲存表示----------------

typedef struct StackNode{
    SElemType data;
    struct StackNode *next;
}StackNode;

typedef struct {
    StackNode *top;
}LinkStack;

//初始化一個空棧
Status InitLStack(LinkStack &LS){
    LS.top = (StackNode *)malloc(sizeof(StackNode));
    if(!LS.top)
        exit(OVERFLOW);
    LS.top->next = NULL;
    return OK;
}

//銷燬棧
Status DestoryLStack(LinkStack &LS){
    StackNode *p, *q;
    p = LS.top;
    while(p){
        q = p;
        p = p->next;
        free(q);
    }
    return OK;
}

//清空棧
Status ClearLStack(LinkStack &LS){
    StackNode *p, *q;
    p = LS.top->next;
    LS.top->next = NULL;
    while(!p){
        q = p;
        p = p->next;
        free(q);
    }
    return OK;
}

//判斷棧是否為空
bool Is_LStackEmpty(LinkStack LS){
    if(!LS.top->next)
        return true;
    return false;
}

//返回棧頂元素
SElemType GetTop(LinkStack LS){
    if(LS.top->next)
        return LS.top->next->data;
    return ERROR;
}

//入棧
Status PushLStack(LinkStack &LS, SElemType e){
    StackNode *InsertPtr;
    InsertPtr = (StackNode *)malloc(sizeof(StackNode));
    if(!InsertPtr)
        exit(OVERFLOW);                 //儲存分配失敗

    InsertPtr->data = e;
    InsertPtr->next = LS.top->next;
    LS.top->next = InsertPtr;
    return OK;
}

//出棧
Status PopLStack(LinkStack &LS, SElemType &e){
    StackNode *DelPtr;
    if(!LS.top->next)
        return ERROR;
    DelPtr = LS.top->next;
    e = DelPtr->data;
    LS.top->next = DelPtr->next;
    free(DelPtr);
    return OK;
}

//返回棧長
int LStackLength(LinkStack LS){
    StackNode *p;
    int len = 0;
    p = LS.top->next;
    while(p){
        len++;
        p = p->next;
    }
    return len;
}

//visit()函式
Status Print(SElemType e){
    printf("%d ", e);
    return OK;
}

//遍歷棧
Status LStackTraverse(LinkStack LS, Status (*visit)(SElemType)){
    StackNode *p;
    p = LS.top->next;
    while(p){
        if(!visit(p->data))
            return ERROR;
        p = p->next;
    }
    return OK;
}


//主函式
int main(){
    LinkStack S;
    SElemType a;

    InitLStack(S);
    printf("輸入5個數字:\n");
    for(int i = 0; i < 5; i++){
        scanf("%d", &a);
        PushLStack(S, a);
    }

    printf("下面是執行遍歷操作的輸出結果:\n");
    LStackTraverse(S, Print);

    printf("\n下面是返回棧長的結果:\n");
    printf("%d\n", LStackLength(S));

    printf("下面是執行出棧後遍歷的結果:\n");
    PopLStack(S, a);
    LStackTraverse(S, Print);

    printf("\n下面是獲得棧頂元素的操作:\n%d\n", GetTop(S));

    printf("下面是判斷棧是否為空的操作(空輸出YES,不空輸出NO和棧長):\n");
    if(Is_LStackEmpty(S))
        printf("YES");
    else
        printf("NO  %d", LStackLength(S));
    return 0;
}

下面是對程式的簡單測試結果: