• 【数据结构】之栈(C语言描述)


      栈(Stack)是编程中最常用的数据结构之一。

      栈的特点是“后进先出”,就像堆积木一样,堆的时候要一块一块堆到最上面,拆的时候需要从最上面一块一块往下拆。栈的原理也一样,只不过它的操作不叫堆和拆,而是叫入栈(或压栈)和出栈(或弹栈)。栈要求我们只能在栈顶(最上面的元素)处进行增加和删除。

      栈可以用顺序表示法(顺序栈)和链式表示法(链栈)。由于栈只需要在一端增删节点,不需要在中间某处增删节点,因此即使栈在应用中大多数做的是增删操作,顺序栈虽然在增删操作时略微逊色于链栈(因为可能会扩容),但其存储密度要高于链栈,因此二者在性能方面可以说是各有各的好处。

      下面的代码是使用 C语言 描述的链栈的代码。

      栈的头文件 Stack.h 中的代码:

    /**
     * 栈(链栈):
     * 本程序中栈的存储方式:栈顶->节点->节点->...->栈底。即:栈顶是第一个元素
     */
    #include <Constant.h>
    
    // 栈中存储的数据的类型
    typedef int ElemType;
    
    // 栈中的节点的数据结构体
    typedef struct StackNode {
        ElemType value;      // 栈节点中存储的数据的值
        struct StackNode* nextNode; // 下一个节点
    } StackNode;
    
    // 栈的数据结构体
    typedef struct Stack {
        StackNode* data;    // 栈中存储的所有节点
        int length;         // 栈的长度
        StackNode* topNode; // 栈顶元素节点
    } Stack;
    
    // 初始化一个空栈
    Status initStack(Stack* S) {
        S->data = (StackNode*)malloc(sizeof(StackNode));
        if(S->data == NULL) {
            printf("初始化栈失败!
    ");
            return FAILURE;
        }
        S->length = 0;
        S->topNode = NULL;
        return SUCCESS;
    }
    
    // 销毁栈
    Status destroyStack(Stack* S) {
        StackNode* tmpNode;
        if(S->data == NULL) {
            printf("栈不存在,销毁失败!
    ");
            return FAILURE;
        }
        while(S->topNode != NULL && S->topNode != S->data) {
            tmpNode = S->topNode;
            S->topNode = S->topNode->nextNode;
            free(tmpNode);
        }
        S->data = NULL;
        S->length = 0;
        S->topNode = NULL;
        return SUCCESS;
    }
    
    // 清空栈
    Status clearStack(Stack* S) {
        StackNode* tmpNode;
        if(S->data == NULL) {
            printf("栈不存在,清空失败!
    ");
            return FAILURE;
        }
        if(S->topNode == NULL) {
            return SUCCESS;
        }
        while(S->topNode != S->data) {
            tmpNode = S->topNode;
            S->topNode = S->topNode->nextNode;
            free(tmpNode);
        }
        S->topNode = NULL;
        S->length = 0;
        return SUCCESS;
    }
    
    // 判断栈是否为空
    Status isStackEmpty(Stack* S) {
        if(S->data == NULL) {
            printf("栈不存在!
    ");
            exit(1);
        }
        if(S->length == 0) {
            return TRUE;
        }
        return FALSE;
    }
    
    // 获取栈中元素的长度
    int getStackLength(Stack* S) {
        if(S->data == NULL) {
            printf("栈不存在!
    ");
            exit(1);
        }
        return S->length;
    }
    
    // 查看栈顶元素的值
    ElemType getTopElem(Stack* S) {
        if(S->data == NULL) {
            printf("栈不存在,获取元素失败!
    ");
            exit(1);
        }
        if(S->topNode == NULL) {
            printf("栈是空栈,获取元素失败!
    ");
            exit(1);
        }
        return S->topNode->value;
    }
    
    // 元素入栈
    Status push(Stack* S, ElemType e) {
        StackNode* tmpNode;
        if(S->data == NULL) {
            printf("栈不存在,元素入栈失败!
    ");
            return FAILURE;
        }
        tmpNode = (StackNode*)malloc(sizeof(StackNode));
        if(tmpNode == NULL) {
            printf("元素入栈失败!
    ");
            return FAILURE;
        }
        tmpNode->value = e;
        S->length++;
        if(S->topNode == NULL) {
            S->topNode = tmpNode;
            S->topNode->nextNode = S->data;
            return SUCCESS;
        }
        tmpNode->nextNode = S->topNode;
        S->topNode = tmpNode;
        return SUCCESS;
    }
    
    // 元素出栈
    StackNode* pop(Stack* S) {
        StackNode* tmpNode;
        if(S->data == NULL) {
            printf("栈不存在,元素出栈失败!
    ");
            exit(1);
        }
        if(S->topNode == NULL) {
            printf("栈是空栈,元素出栈失败!
    ");
            return NULL;
        }
        tmpNode = S->topNode;
        S->topNode = S->topNode->nextNode;
        if(S->topNode == S->data) {
            S->topNode = NULL;
        }
        tmpNode->nextNode = NULL;
        S->length--;
        return tmpNode;
    }
    
    // 遍历栈中的元素
    void traverseStack(Stack* S) {
        StackNode* tmpNode;
        if(S->data == NULL) {
            printf("栈不存在,遍历失败!
    ");
            exit(1);
        }
        if(S->topNode == NULL) {
            printf("栈是空栈,遍历失败!
    ");
            exit(1);
        }
        printf("遍历栈:");
        tmpNode = S->topNode;
        while(tmpNode != S->data) {
            printf("%-4d", tmpNode->value);
            tmpNode = tmpNode->nextNode;
        }
        printf("
    ");
    }
    
    // 栈的测试函数
    int testStack() {
        // 数据声明
        Stack stack;
        StackNode* node;
        int i;
        // 初始化栈
        if(initStack(&stack) == SUCCESS) {
            printf("初始化栈成功!
    ");
        }
        // 判断栈是否是空栈
        printf("栈是否为空栈?%s
    ", isStackEmpty(&stack) == TRUE ? "" : "");
        // 元素入栈
        for(i = 1; i <= 5; i++) {
            if(push(&stack, i) == SUCCESS) {
                printf("元素%d入栈成功!
    ", i);
            }
        }
        // 遍历栈中的元素
        traverseStack(&stack);
        // 元素出栈
        node = pop(&stack);
        if(node != NULL) {
            printf("元素%d成功出栈!
    ", node->value);
        }
        // 遍历栈中的元素
        traverseStack(&stack);
        // 查看栈顶元素的值
        printf("栈顶元素的值是:%d
    ", getTopElem(&stack));
        // 获取栈的长度
        printf("栈的当前长度:%d
    ", getStackLength(&stack));
        // 清空栈
        if(clearStack(&stack) == SUCCESS) {
            printf("清空栈成功!
    ");
        }
        // 销毁栈
        if(destroyStack(&stack) == SUCCESS) {
            printf("销毁栈成功!
    ");
        }
        return 0;
    }

      常量类 Constant.h 中定义了一些常量,其代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define TRUE 1
    #define FALSE 0
    
    #define SUCCESS 1
    #define FAILURE 0
    
    typedef int Status;

      主函数所在的文件 main.c 中的代码如下:

    #include <Stack.h>
    
    int main() {
        testStack();
        return 0;
    }

      运行结果如下:

    初始化栈成功!
    栈是否为空栈?是
    元素1入栈成功!
    元素2入栈成功!
    元素3入栈成功!
    元素4入栈成功!
    元素5入栈成功!
    遍历栈:5   4   3   2   1
    元素5成功出栈!
    遍历栈:4   3   2   1
    栈顶元素的值是:4
    栈的当前长度:4
    清空栈成功!
    销毁栈成功!
    
    Process returned 0 (0x0)   execution time : 0.016 s
    Press any key to continue.
  • 相关阅读:
    【2021-03-31】人生十三信条
    【2021-03-30】证明自己是人类忠实的朋友
    【2021-03-29】万物本是无序
    缀点成线
    1比特与2比特字符
    Solution -「LOCAL」「cov. 牛客多校 2020 第三场 I」礼物
    Solution -「HNOI 2007」「洛谷 P3185」分裂游戏
    Solution -「CF 1372E」Omkar and Last Floor
    Solution -「POJ 3710」Christmas Game
    Solution -「CF 1380F」Strange Addition
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6667738.html
Copyright © 2020-2023  润新知