zoukankan      html  css  js  c++  java
  • 【数据结构】之栈(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.
  • 相关阅读:
    POJ 3831 &amp; HDU 3264 Open-air shopping malls(几何)
    LeetCode Maximum Depth of Binary Tree
    解决下载Android Build-tools 19.1.0失败
    cocos2d-x3.6 连连看随机地图实现
    Swift初体验(三)
    Delphi XE7中新并行库
    mysql 权限控制具体解释
    C实例--推断一个字符串是否是回文数
    阿里 2014校招机试题 求存放整数的二叉树相差最大的两节点之差绝对值
    Choosing Between ElasticSearch, MongoDB &amp; Hadoop
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6667738.html
Copyright © 2011-2022 走看看