zoukankan      html  css  js  c++  java
  • C语言 复杂的栈(链表栈)

    //复杂的栈--链表栈
    #include<stdio.h>
    #include<stdlib.h>
    
    
    #define datatype int//定义链表栈数据类型
    //定义链表栈结构
    struct stacklink{
        datatype data;
        struct stacklink *pnext;
    };
    
    typedef struct stacklink StackLink;
    
    //判断栈是否为空
    int isempty(StackLink *phead);
    //进栈
    StackLink * push(StackLink *phead, datatype num);
    //出栈
    StackLink * pop(StackLink *phead, StackLink *pout);
    //清空
    StackLink * setempty(StackLink *phead);
    //遍历栈中的数据
    void findall(StackLink *phead);
    
    //链表栈容量无限大,但是代价是增加链表遍历成本
    
    void main(){
        //定义链表栈的头指针
        StackLink * phead = NULL;
        //压栈
        phead = push(phead, 1);
        phead = push(phead, 2);
        phead = push(phead, 3);
        phead = push(phead, 4);
        phead = push(phead, 5);
        //打印栈中的数据
        findall(phead);
        //出栈
        StackLink *pout = (StackLink *)malloc(sizeof(StackLink));
        phead = pop(phead, pout);
        printf("
    弹出的元素是%d;
    ", pout->data);
        free(pout);
        ////全部出栈
        //while (phead!=NULL){
        //    StackLink *pout = malloc(sizeof(StackLink));
        //    phead = pop(phead, pout);
        //    printf("
    弹出的元素是%d;
    ", pout->data);
        //    free(pout);
        //}
        printf("
    ================================
    ");
        //打印栈中的数据
        findall(phead);
        printf("
    ================================
    ");
        //清空栈内元素
        phead = setempty(phead);
        //打印栈中的数据
        findall(phead);
        system("pause");
    }
    
    //判断栈是否为空
    int isempty(StackLink *phead){
        if (phead == NULL)
        {
            return 1;
        }
        else{
            return 0;
        }
    }
    
    //进栈
    StackLink * push(StackLink *phead, datatype num){
        //分配内存空间
        StackLink *p = (StackLink *)malloc(sizeof(StackLink));
        StackLink *p1 = phead;
        p->data = num;
        p->pnext = NULL;
        //判断栈是否为空
        if (isempty(phead))
        {
            //栈为空
            phead = p;
            //注意:这里是给指针副本phead赋值,但是main()函数里phead的值并没有变化
            //要在函数里修改一个指针的值,应该使用二级指针,但是根据代码优化原则,尽量不使用二级指针,
            //因此我们将phead当做返回值返回
        }
        else{
            while (p1->pnext != NULL){
                p1 = p1->pnext;
            }
            p1->pnext = p;
            //这里的phead->pnext会直接影响main()函数里phead的值,因为phead->pnext本质上等于(*phead).pnext
            //修改的是phead指针指向数据的值,而不是修改phead本身
        }
        return phead;
    }
    
    //遍历栈中的数据
    void findall(StackLink *phead){
        StackLink *p = phead;
        while (p != NULL){
            printf("%d
    ", p->data);
            p = p->pnext;
        }
    }
    
    //出栈
    StackLink * pop(StackLink *phead, StackLink *pout){
        if (phead == NULL)//判断栈是否为空
        {
            return NULL;
        }
        else{
            pout->pnext = NULL;
            //不为空
            //出栈,每次弹出最后一个
            //分两种情况
            //1.只有一个元素,只有一个元素,只需要弹出头指针本身
            if (phead->pnext == NULL)
            {
                //pout = phead; 错误,这样只是改变pout指向的地址,而free(phead)会彻底释放phead指向地址的内存
                //结果就是pout也为NULL
                pout->data = phead->data;
    
                //注意:链表栈删除必须释放内存
                free(phead);
                phead = NULL;
                //这个改变形参phead的值,所以只能返回phead,而有任何地方修改pout的值
                return phead;
            }
            //2.多个元素,找到倒数第二个元素
            else{
                StackLink *p = phead;
                while (phead->pnext->pnext != NULL){
                    phead = phead->pnext;
                }
                pout->data = phead->pnext->data;
                //删除栈中最后一个元素
                free(phead->pnext);
                phead->pnext = NULL;
                return p;
            }
    
        }
    }
    
    //清空
    StackLink * setempty(StackLink *phead){
        //清空的思路是,1,2,3,4,5通过头指针找到1,将2删除,把3移到2的位置上,再删除3
        //不太清楚循环次数,所以用while
        StackLink *p = NULL;
        while (phead->pnext != NULL){//当第二个元素是NULL的时候,退出循环
            //删除第二个
            //p是第三个的指针
            p = phead->pnext->pnext;
            //开始删除第二个
            free(phead->pnext);
            phead->pnext = p;
        }
        //最后删除第一个元素
        free(phead);
        return NULL;
    }

  • 相关阅读:
    关于CQRS(老外经典好文)
    关于Autofac的使用陷阱
    文件写入文件分布式系统(asp.net C#)
    NET Framework 4.5.2
    asp.net开源
    关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }
    sql SELECT时的with(nolock)选项说明
    树形结构的数据库表Schema设计
    C#操作符??和?:
    Byte[]和BASE64之间的转换
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5230658.html
Copyright © 2011-2022 走看看