zoukankan      html  css  js  c++  java
  • C++栈学习——顺序栈和链栈的差别

    • C++中栈有顺序栈和链栈之分。在顺序栈中,定义了栈的栈底指针(存储空间首地址base)、栈顶指针top以及顺序存储空间的大小stacksize(个人感觉这个数据成员是能够不用定义的)
    //顺序栈数据结构C++类声明(基类)
    template <typename ElemType>
    class SqStack 
    {
    public:
        void clear();                                                 //把顺序栈置空
        int getLength();                                              //求顺序栈中元素个数
        int getstackSize();                                     //返回当前已分配的存储空间的大小
        Status getTop(ElemType & e);                                  //读栈顶的元素
        bool isEmpty();                                               //推断顺序栈是否为空
        SqStack<ElemType> operator =(SqStack<ElemType> rightS);       //重载赋值运算符的定义
        Status pop(ElemType & e);                                     //弹出栈顶元素到e
        void push(ElemType & e );                                     //在栈顶压入元素e
    //*****************************以下为系统自己主动调用构造函数及析构函数声明******************************//
    
        SqStack(); //顺序栈构造函数
        virtual ~SqStack();//顺序栈析构函数
        SqStack (const SqStack<ElemType>& otherS);//顺序栈拷贝初始换构造函数
    
    protected:
        ElemType *base;
        ElemType *top;
        int stackSize;//顺序存储空间的大小
    };
    • 而对于链栈来说,它仅仅定义栈顶指针。
    template<typename ElemType>
    class Linkstack
    {
    
    private:
        class LinkNode
        {
        public:
            ElemType data;
            LinkNode *next;
        };
        typedef LinkNode * NodePointer;
    
    public:
        void clear();
        int getlength();
        void display();
        void randLinkStack();
        Linkstack <ElemType> operator = (Linkstack <ElemType> rightS);
    
    protected:
        NodePointer top;
    
    };

    事实上这二者的差别是由顺序表和链表的存储结构决定的,在空间上,顺序表是静态分配的,而链表则是动态分配的;就存储密度来说:顺序表等于1,而链式表小于1。可是链式表能够将非常多零碎的空间利用起来;顺序表查找方便。链式表插入和删除时非常方便。


    顺序表的这样的静态存储的方式,决定了必须至少得有首地址和末地址来决定一个空间。否则,不知道查找到哪了。链式表每一个节点存储了下一个节点的指针信息,故,对于链栈来说,仅仅须要一个top指针就可以查找到整个栈。


    另外,顺序栈和链栈的top指针有差别,顺序栈的top指针指向栈定的空元素处,top-1才指向栈定元素,而链栈的top指针相当于链表的head指针一样,指向实实在在的元素。
    另外附自己写的顺序栈和链栈的随机产生函数:

    //顺序栈:
    template<typename ElemType>
    void MyStack<ElemType>::RandStack()
    {
        int *p;
        ElemType n;
        ElemType Elem[11];
        srand(time(NULL));
        n=rand()%10+1;
        cout<<"产生的随机栈的深度为:"<<n<<endl;
        cout<<"产生的随机栈元素为:"<<endl;
        for (int i = 0; i < n; i++)
        {
            Elem[i]=rand()%100+1;
            cout<<Elem[i]<<"  ";
        }
        cout<<endl;
        base=new ElemType[n];
        assert(base!=0);
        top=base;
        stackSize=n;
        for (int j = 0; j < n; j++)
            *(base+j)=Elem[j];
        top=base+n;
        cout<<"随机产生的栈为:"<<endl;
        for (int i = 0; i < stackSize; i++)
            cout<<"  "<<*(base+i);
        cout<<endl;
        cout<<"  ♂";
        for (int i = 1; i <stackSize ; i++)
        {
            setw(4);
            cout<<"    ";
        }
        cout<<"  ♂"<<endl;
        cout<<" base";
        for (int i = 1; i <stackSize ; i++)
        {
            setw(4);
            cout<<"    ";
        }
        cout<<" top"<<endl;
    
    }
    
    template<typename ElemType>
    void MyStack<ElemType>::display()
    {
        int n=top-base;
        cout<<"当前栈为:"<<endl;
        for (int i = 0; i < n; i++)
            cout<<"  "<<*(base+i);
        cout<<endl;
        cout<<"  ♂";
        for (int i = 1; i <n ; i++)
        {
            setw(4);
            cout<<"    ";
        }
        cout<<"  ♂"<<endl;
        cout<<" base";
        for (int i = 1; i <n ; i++)
        {
            setw(4);
            cout<<"    ";
        }
        cout<<" top"<<endl;
    }
    
    //链栈
    template<typename ElemType>
    void Linkstack<ElemType>::display()
    {
        NodePointer r;
        int num=0;
        r=top;
        while (r)
        {
            cout<<r->data<<"  ";
            r=r->next;
            num++;
        }
        cout<<endl;
        for(int i=0;i<num-1;i++)
            cout<<setw(4)<<"  ";
        cout<<"↑"  ;
        cout<<endl;
        for(int i=0;i<num-1;i++)
            cout<<setw(4)<<"  ";
        cout<<"top"<<endl;
    
    }
    
    template <typename ElemType>
    void Linkstack<ElemType>::randLinkStack()
    {
        ElemType elem[11];
        srand(unsigned(time(NULL)));
        int n;
        n=rand()%10+1;
        cout<<"the number of the stack is:"<<n<<endl;
        cout<<"the elements here are:";
        for (int i = 0; i < n; i++)
        {
            elem[i]=rand()%100+1;
            cout<<elem[i]<<"  ";
        }
        cout<<endl;
        NodePointer p,s;
        p=NULL;
        for (int i = 0; i < n; i++)
        {
            s=new(LinkNode);
            assert(s!=NULL);
            s->data=elem[i];
            s->next=p;
            p=s;
        }
        top=p;
        cout<<"the stack produced is:"<<endl;
        NodePointer r;
        int num=0;
        r=top;
        while (r)
        {
            cout<<r->data<<"  ";
            r=r->next;
            num++;
        }
        cout<<endl;
        for(int i=0;i<num-1;i++)
            cout<<setw(4)<<"  ";
        cout<<"↑"  ;
        cout<<endl;
        for(int i=0;i<num-1;i++)
            cout<<setw(4)<<"  ";
        cout<<"top"<<endl;
    }
    
  • 相关阅读:
    机器学习(04)——常用专业术语
    C# 线程同步的三类情景
    线程同步的情景之三
    线程同步的情景之二
    线程同步的情景之一
    Thread.Sleep(0) vs Sleep(1) vs Yeild
    Visual Studio 实用扩展推荐
    为革命保护视力 --- 给 Visual Studio 换颜色
    免费的精品: Productivity Power Tools 动画演示
    如何扩展 Visual Studio 编辑器
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7389308.html
Copyright © 2011-2022 走看看