数据结构栈和队列链式存储结构实例讲解
时间:2018-11-09
本文章向大家介绍数据结构栈和队列链式存储结构实例讲解,需要的朋友可以参考一下
#include <iostream>
#include<string.h>
#include<string.h>
static int n; //用于输入货架(货架即为栈)的大小
using namespace std;
//信息结构体
typedef struct /*Inform*/ //可以去掉Inform,在需要在结构体中定义结构体对象(指针)时不能去掉
{
string name;
int a;
}Inform;
typedef struct /*Inform*/ //可以去掉Inform,在需要在结构体中定义结构体对象(指针)时不能去掉
{
string name;
int a;
}Inform;
//栈的*顺序*结构体
typedef struct Node
{
Inform e;
struct Node *next;
}StackNode,*LinkStack;
typedef struct Node
{
Inform e;
struct Node *next;
}StackNode,*LinkStack;
//队列*链式*结构体
typedef struct QNode
{
Inform e;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct QNode
{
Inform e;
struct QNode *next;
}QNode,*QueuePtr;
//指向链式队列的头尾指针
typedef struct
{
QueuePtr fro;
QueuePtr rear;
}LinkQueue;
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);
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;
}
{
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;
}
}
{
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;
}
{
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;
}
}
//而未存储下一个结点)还有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;
}
}
{
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;
}
}
{
//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存入的指针,则会使存入的元素空间释放,即存入进去的内容被删除
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java 15正式发布,腾讯做出了突出贡献
- Mybatis是如何向Spring注册Mapper的
- 打卡群刷题总结0917——买卖股票的最佳时机
- Fiddler对安卓App抓包(逍遥模拟器APP)
- 为何Android 7.0 以上Charles和Fiddler无法抓取HTTPS包?
- 快速上手百度大脑EasyDL专业版·物体检测模型(附代码)
- 极端情况下收缩 Go 进程的线程数
- C++核心准则T.60:最小化模板对上下文的依赖
- C++核心准则T.61:不要过度参数化成员(SCARY)
- C++核心准则T.62:将非依赖类模板成员放入非模板基类中
- C++核心准则T.64:使用特化提供类模板的不同实现
- C++核心准则T.68:在模板中使用{}代替()以避免歧义
- C++核心准则T.69:在模板内部,不要进行不受限制的非成员函数调用
- C++核心准则T.80:不要天真地模板化类继承
- 贪心算法求解:王者荣耀购买点券最优策略