• 栈的实现


    栈的定义:

    栈是一种特殊的线性表

    栈仅能在线性表的一端进行操作

    栈顶:同意操作的一端

    栈底:不同意操作的一端


    栈的性质:

    LIFO 后进先出原则



    链式栈

    linkStack.h


    #ifndef _LINKSTACK_H_
    #define _LINKSTACK_H_


    typedef void LinkStack; //给void 起一个新的名字,是LinkStack,这样写的会让函数的安全性变高。在main函数中不能改变类型


    LinkStack* LinkStack_Create(); //创建栈


    void LinkStack_Destroy(LinkStack* stack); //销毁栈


    void LinkStack_Clear(LinkStack* stack); //清空栈


    int LinkStack_Push(LinkStack* stack, void* item); //压栈


    void* LinkStack_Pop(LinkStack* stack); //出栈


    void* LinkStack_Top(LinkStack* stack); //栈顶


    int LinkStack_Size(LinkStack* stack); //栈的大小


    #endif



    LinkStack.c

    .c的一大特色是代码复用,就是在当中增加写LinkList.h链表时候的代码。降低代码量


    #include <malloc.h>
    #include "LinkStack.h"
    #include "LinkList.h" //代码复用时候增加的头文件


    typedef struct _tag_LinkStackNode
    {
        LinkListNode header;
        void* item;
    } TLinkStackNode;


    LinkStack* LinkStack_Create() //创建顺序栈和创建线性表是一样的
    {
        return LinkList_Create();
    }


    void LinkStack_Destroy(LinkStack* stack)
    {
        LinkStack_Clear(stack); //须要想将栈中的元素清空。然后再使用链表销毁的方式销毁,这样防止内存泄漏
        LinkList_Destroy(stack);
    }


    void LinkStack_Clear(LinkStack* stack) //清空栈。由于栈仅仅能从栈顶出,那仅仅要栈不是空的。就不停的出栈(弹出栈顶元素)
    {
        while( LinkStack_Size(stack) > 0 )
        {
            LinkStack_Pop(stack);
        }
    }


    int LinkStack_Push(LinkStack* stack, void* item) //入栈   所要进入的栈  所要进入元素的地址
    {
        TLinkStackNode* node = (TLinkStackNode*)malloc(sizeof(TLinkStackNode)); //创建一个node
        int ret = (node != NULL) && (item != NULL); //确定一个返回值,依据这个值观察进栈是否成功
         //创建内存成功,node不为空  且  增加的元素的地址不为空
        if( ret )
        {
            node->item = item; //将数据item写入node->item中
            
            ret  = LinkList_Insert(stack, (LinkListNode*)node, 0); //增加栈中
        }
        
        if( !ret ) //释放内存
        {
            free(node);
        }
        
        return ret;
    }


    void* LinkStack_Pop(LinkStack* stack)
    {
        TLinkStackNode* node = (TLinkStackNode*)LinkList_Delete(stack, 0);
        void* ret = NULL;
        
        if( node != NULL )
        {
            ret = node->item;
            
            free(node);
        }
        
        return ret;
    }


    void* LinkStack_Top(LinkStack* stack) //栈顶
    {
        TLinkStackNode* node = (TLinkStackNode*)LinkList_Get(stack, 0); //依据链表的获取得到栈顶
        void* ret = NULL;
        
        if( node != NULL )
        {
            ret = node->item; //不为空。得到栈顶元素
        }
        
        return ret; //返回item
    }


    int LinkStack_Size(LinkStack* stack)
    {
        return LinkList_Length(stack);
    }


    main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "LinkStack.h"


    /* run this program using the console pauser or add your own getch, system("pause") or input loop */


    int main(int argc, char *argv[]) 
    {
        LinkStack* stack = LinkStack_Create();
        int a[10];
        int i = 0;
        
        for(i=0; i<10; i++)
        {
            a[i] = i;
            
            LinkStack_Push(stack, a + i);
        }
        
        printf("Top: %d ", *(int*)LinkStack_Top(stack));
        printf("Length: %d ", LinkStack_Size(stack));
        
        while( LinkStack_Size(stack) > 0 )
        {
            printf("Pop: %d ", *(int*)LinkStack_Pop(stack));
        }
        
        LinkStack_Destroy(stack);
        
    return 0;
    }


  • 相关阅读:
    优秀的JavaScript模块是怎样炼成的(转发)
    从发展历史理解 ES6 Module(转发)
    JavaScript 模块演化简史(转发)
    objcopy 格式转换
    链接操作
    fflush()
    为什么栈地址从高到低生长,堆从低到高
    C语言中,a[-1] (负数下标)的用途
    va_list 、va_start、 va_arg、 va_end 使用说明
    docker 部署 redis
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/6848639.html
Copyright © 2020-2023  润新知