数据结构栈和队列链式存储结构实例讲解

时间:2018-11-09
本文章向大家介绍数据结构栈和队列链式存储结构实例讲解,需要的朋友可以参考一下
#include <iostream>
#include<string.h>
static int n;                       //用于输入货架(货架即为栈)的大小
using namespace std;
 
//信息结构体
typedef struct /*Inform*/      //可以去掉Inform,在需要在结构体中定义结构体对象(指针)时不能去掉
{
    string name;
    int a;
}Inform;
 
//栈的*顺序*结构体
typedef struct Node
{
    Inform e;
    struct Node *next;
}StackNode,*LinkStack;
 
//队列*链式*结构体
typedef struct QNode
{
    Inform e;
    struct QNode *next;
}QNode,*QueuePtr;
 
//指向链式队列的头尾指针
typedef struct
{
    QueuePtr fro;
    QueuePtr rear;
}LinkQueue;
void Found1(LinkStack &s);      //货物上架
void Foundd(LinkQueue &d);      //创建顺序队列
void TurnsZ1(LinkStack &s1,LinkQueue d);      //对于前天未剩余(第一天)倒货
void TurnsZ2(LinkStack &s1,LinkStack s2,LinkStack s3);      //对于前天有剩余倒货
void Print(LinkStack s1);
int main()
{
    cout << "请输入每次上货的最大值\t";
    cin >> n;
    LinkStack s1,s2,s3;
    s1=s2=s3=NULL;      //是否有必要定义构造函数,即建立一个空栈  建立一个队列,使其头尾指针指向队列未存货物信息的空结点
    LinkQueue d;
    cout<<"第一天货物上架"<<endl;
    Found1(s1);      //输入货物信息
    Foundd(d);
    TurnsZ1(s1,d);
    Print(s1);
    cout<<"第二天货物上架"<<endl;
    if(s1==NULL)
    {
        Found1(s1);
        TurnsZ1(s1,d);
        Print(s1);
    }
    else
    {
        Found1(s2);
        TurnsZ2(s1,s2,s3);
        Print(s1);
    }
    return 0;
}
void Found1(LinkStack &s)
{
    s=NULL;      //定义一个空栈,s连接在p上,即p->next=NULL
    Inform i;
    i.name="";
    cout<<"输入break表示停止输入:"<<endl;
    while(1)
    {
       StackNode *p;
       p=new StackNode;
       cin>>i.name;
       if(i.name=="break")
        break;
       cin>>i.a;
       p->e=i;
       p->next=s;
       s=p;
    }
}
void Foundd(LinkQueue &q)
{
    q.fro=q.rear=new QNode;
    q.fro->next=NULL;
    q.rear->next=NULL;
}
void TurnsZ1(LinkStack &s1,LinkQueue d)      //此处队列表现出来的问题为 d.fro始终与d.rear相等。实际上为对接点的创建(多次使用只创建一次导致一直在修该此指针
                                             //而未存储下一个结点)还有delete的问题,怎填的结点指针并不能delete,否则该节点将会被删除
{
    Inform i;
    //QNode *p=new QNode;      若无下面的,知识在修改队列第一个元素指向的值,而不是继续添加
    StackNode *s=new StackNode;
    while(s1!=NULL)
    {
        QNode *p=new QNode;     //此处十分重要
        i=s1->e;     //i=s1.e不正确 ,调用对象的成员时用“.”,如果是指针或者引用时,利用“->”调用其成员
        s=s1;
        s1=s->next;
        delete s;
        p->e=i;
        p->next=NULL;
        d.rear->next=p;
        d.rear=p;
        //cout<<"rear指向的名字"<<d.rear->e.name<<endl;
        //cout<<"fro指向的名字"<<d.fro->next->e.name<<endl;      //《问题》此处fro 与 rear 同时移动
    }
    QNode *p=new QNode;
    while(d.fro!=d.rear)
    {
        StackNode *s=new StackNode;
        p=d.fro->next;
        i=p->e;
        d.fro->next=p->next;
        if(p==d.rear)
            d.rear=d.fro;
        delete p;
        s->e=i;
        s->next=s1;
        s1=s;
    }
}
void TurnsZ2(LinkStack &s1,LinkStack s2,LinkStack s3)
{
    Inform i;
    while(s1!=NULL)
    {
        StackNode *s=new StackNode;
        s=s1;
        s1=s->next;
        s->next=s3;
        s3=s;
    }
    while(s2!=NULL)
    {
        StackNode *s=new StackNode;
        s=s2;
        s2=s->next;
        s->next=s1;
        s1=s;
    }
    while(s3!=NULL)
    {
        StackNode *s=new StackNode;
        s=s3;
        s3=s->next;
        s->next=s1;
        s1=s;
    }
}
void Print(LinkStack s1)
{
    //StackNode *s=new StackNode;
    while(s1!=NULL)
    {
        cout<<s1->e.name<<" "<<s1->e.a<<endl;
        s1=s1->next;
    }
}
 
栈与队列链式存储结构:
      1:掌握栈与队列的初始化问题,可以通过画图进一步理解并记忆其核心内容
            a:栈,初始化时申请一个 *S 指向NULL的空地址,存入时,申请空间并与S连接即可(注意栈的尾部结点的next->NULL)
            b:   队列:首先创建两个指针  *pro  he  *rear 指向同一个空节点,并令其next->NULL,存入时,创建新结点连在rear后面,并且将rear指向新节点,删除队列元素时,pro不                                动,删除pro->next即可
       2:特别问题:
             在存入和删除元素时,要注意新节点的创建与删除。
                    a:创建——存入一个元素需要创建一个新指针,不能创建一个多次对其赋值,这样不会存入,而是在不断改变第一个元素的值
                    b:delete也是如此,在元素存入时,若delete存入的指针,则会使存入的元素空间释放,即存入进去的内容被删除