zoukankan      html  css  js  c++  java
  • 顺序栈与链式栈

      是限定尽在表尾进行插入或者删除操作的线性表,分为顺序栈链式栈

      对于malloc()一次申请的内存地址,在逻辑上是连续的,也就是我们用的时候可以当做连续的来用,但是在物理内存上未必是连续的;

      顺序栈:

        利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设top指示栈顶元素在顺序栈中的位置,top永远指向栈顶元素的下一个元素位置,下面我们来看         一下顺序栈的基本操作和其应用如下:

          链式栈:

        由单链表来实现,具体操作是在头指针head的后面进行插入或者删除操作;

      顺序栈和链式栈比较

        顺序栈需要固定空间长度,存在溢出问题,而链式栈不存在;

        链式栈的每个元素都有指针域,增加了空间开销,并且求栈长度时候时间复杂度为O(n),也就是遍历整个链;

    #include <iostream>
    using namespace std;
    
    #define  STACK_INIT_SIZE 100
    #define  STACKINCREMRNT 10
    struct Stack
    {
        int *base;
        int *top;
        int stacksize;
    };
    bool InitStack(Stack &s)
    {
        s.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));// 分配内存
        if (!s.base)//detect 
        {
            exit(OVERFLOW);
        }
        s.top=s.base;//empty stack
        s.stacksize=STACK_INIT_SIZE;//init stacksize
        return true;
    }
    bool StackPush(Stack &s,int e)//
    {
        if (s.top-s.base>=s.stacksize)//very important, s.top, s.base and s.stacksize all changed
        {
            s.base=(int*)realloc(s.base,(s.stacksize+STACKINCREMRNT)*sizeof(int));
            if (!s.base)
            {
                exit(OVERFLOW);
            }
            s.top=s.base+s.stacksize;
            s.stacksize+=STACKINCREMRNT;
        }
        *s.top=e;
        s.top++;
        return true;
    }
    
    bool GetTop(Stack &s,int &e)
    {
        if (s.top==s.base)
        {
            return false;
        }
        else
            e=*(s.top-1);
        return true;
    }
    
    bool StackPop(Stack &s, int &e)
    {
        if (s.base==s.top)
        {
            return 0;
        }
        else
        {
            s.top--;
            e=*s.top;
        }
        return true;
    }
    
    bool StackEmpty(Stack &s)
    {
        if (s.base==s.top)
        {
            return true;
        }
        else
            return false;
    
    }
    void main()
    {
        Stack s={0};
        bool stats=InitStack(s);
        if (stats)
        {
            cout<<"initial stack success!"<<endl;
        }
        else
            cout<<"initial stack error!";
        int pushnum=0,pushnum2=0;
        cout<<"please input the number:";
        cin>>pushnum;
        StackPush(s,pushnum);
        cout<<"please input the number:";
        cin>>pushnum2;
        StackPush(s,pushnum2);
        int popnum=0;
        StackPop(s,popnum);
        StackPop(s,popnum);
        cout<<"the popnum is:"<<popnum<<endl;
        int topnum=0;
        if (GetTop(s,topnum))
        {
            cout<<topnum<<endl;
        }
        else
        {
            cout<<"the stack is empty"<<endl;
        }
    }
    
    //顺序栈应用  由十进制转换为8进制数
    void Convers8()
    {
        int num;
        Stack s={0};
        InitStack(s);
        cout<<"please input the 10 number:";
        cin>>num;
        while (num)
        {
            StackPush(s,num%8);
            num/=8;
        }
        int num8;
        while(!StackEmpty(s))
        {
            StackPop(s,num8);
            cout<<num8;
        }
    }
    void main()
    {
        Convers8();
        cout<<endl;
    }

    下面是链式栈的基本操作

    #include <iostream>
    using namespace std;
    //栈的链式存储结构
    //栈顶指针为链表的头结点
    //插入元素要在头结点后面插入
    
    struct ChainStack
    {
        ChainStack * next;
        int data;
    };
    
    ChainStack *InitStack()
    {
        ChainStack*    head=(ChainStack*)malloc(sizeof(ChainStack));
        head->next=NULL;
        return head;
    }
    
    void PushStack(ChainStack *head,int num)//在头结点后插入
    {
        ChainStack *p=(ChainStack*)malloc(sizeof(ChainStack));
        p->data=num;
        p->next=head->next;
        head->next=p;
    }
    bool PopStack(ChainStack *head,int &num)
    {
        
        if (head->next==NULL)
        {
            cout<<"the stack is empty"<<endl;
            return false;
        }
        else
            {
                ChainStack *p=head->next;
                num=p->data;
                head->next=p->next;
                free(p);//别忘了释放内存
            }
        return true;
    }
    
    void main()
    {
        ChainStack*s=NULL;
        s=InitStack();
        int pushnum=0;
        cout<<"请输入栈区总长度:";
        int leng;
        cin>>leng;
        for (int i=0;i<leng;i++)
        {
            cout<<"please input the "<<i+1<<" number: ";
            cin>>pushnum;
            PushStack(s,pushnum);
        }
        int popnum=0;
        for ( ;PopStack(s,popnum); )
        {
            cout<<"the pop num is "<<popnum<<endl;
        }
    }

     下面也是链式栈的操作,不过加了栈顶和栈底指针罢了

    #include <iostream>
    using namespace std;
    struct Node
    {
        Node * next;
        int data;
    };
    
    struct queue
    {
        Node *top;
        Node *base;
    };
    
    queue *QuPush(queue *HQ,int x)
    {
        Node *s=NULL;
        Node *p=NULL;
        s=(Node *)malloc(sizeof(Node));
        s->data=x;
        s->next=NULL;
        if (HQ->base==NULL)
        {
            HQ->base=s;
            HQ->top=s;
        }
        else
        {
            HQ->top->next=s;
            HQ->top=s;
        }
        return HQ;
    }
    void QuPop(queue *HQ,int &e)
    {
        Node *RetNode=NULL;
        if (HQ->base==NULL)
        {
            cout<<"empty"<<endl;
            return;
        }
        
        else
        {
            
            e=HQ->top->data;
            Node *p=HQ->base;
            if (HQ->base==HQ->top)//只有一个元素的时候 将栈置空
            {
                HQ->base=NULL;
                HQ->top=NULL;
            }
            while(p->next!=HQ->top)//有多个元素的时候将top指针下移
            {
                p=p->next;
            }
            free(HQ->top);
            HQ->top=p;
            HQ->top->next=NULL;
        }
        return;
    }
    
    void main()
    {
        int pushnum=0;
        cout<<"请输入栈区总长度:";
        int leng;
        cin>>leng;
        queue *q=(queue*)malloc(sizeof(queue));
        q->base=NULL;
        q->top=NULL;
        for (int i=0;i<leng;i++)
        {
            cout<<"please input the "<<i+1<<" number: ";
            cin>>pushnum;
            q=QuPush(q,pushnum);
        }
        int c;
        QuPop(q,c);
        QuPop(q,c);
        QuPop(q,c);
        QuPop(q,c);
        cout<<c<<endl;
    }

        

  • 相关阅读:
    java 自定义表单 动态表单 表单设计器 工作流引擎 flowable 设计方案
    设置Springboot返回jackson数据序列化
    SpringCloud Alibaba 报 AbstractMethodError 是版本兼容问题导致
    Springboot进阶JDBC、Druid、Mybatis、Swagger、SpringMVC、Mail
    java 自定义表单 动态表单 表单设计器 工作流引擎 flowable 项目源码
    springcloud Alibaba 微服务 flowable 工作流 自定义表单 vue.js前后分离
    ClassLoader读取文件,springboot打jar包后读取不到
    Nginx/Tomcat/Apache的优缺点和区别
    Swagger3 相比2配置变了
    webloginc配置项目根目录
  • 原文地址:https://www.cnblogs.com/mu-tou-man/p/3898076.html
Copyright © 2011-2022 走看看