数据结构上机实验报告 - 队列和树状结构的应用
一. 看病排队候诊问题
- 问题描述 医院各科室的医生有限,因此病人到医院看病时必须排队候诊,而病人病情有轻重之分,不能简单地根据先来先服务地原则进行诊断治疗,所以医院根据病人的病情规定了不同的优先级别。医生在诊断治疗时,总是选择优先级别高的病人进行诊治,如果遇到两个优先级别相同的病人,则选择最先来排队的病人进行诊治。
- 设计要求 用队列模拟上述看病排队候诊的问题,建立两个队列分别对应两个不同的优先级别,按照 从终端读入的输入数据的方式进行模拟管理。输入1,表示有新的病人加入队列候诊,根据病情指定其优先级别;输入2,表示医生根据优先级别为病人进行诊治;输入3,表示退出系统。
- 数据结构 解决看病排队候诊的问题,可以采用链式队列来实现。
#include <iostream>
using namespace std;
typedef struct QNode {
int data;
struct QNode* next;
}QNode;
typedef struct LiQueue{
QNode* front;
QNode* rear;
}LiQueue;
LiQueue* A, *B;
void initQueue(LiQueue*& lqu) {
lqu = (LiQueue*)malloc(sizeof(LiQueue));
lqu->front = lqu->rear = NULL;
}
bool isQueueEmpty(LiQueue* lqu) {
if (lqu->rear == NULL || lqu->front == NULL) {
return true;
}
else {
return false;
}
}
void enQueue(LiQueue* lqu, int x) {
QNode* p;
p = (QNode*)malloc(sizeof(QNode));
p->data = x;
p->next = NULL;
if (lqu->rear == NULL) {
lqu->front = lqu->rear = p;
}
else
{
lqu->rear->next = p;
lqu->rear = p;
}
}
int deQueue(LiQueue* lqu) {
QNode* p;
if (lqu->rear == NULL) {
return 0;
}
else {
while (lqu->rear != NULL)
{
p = lqu->front;
if (lqu->front == lqu->rear) {
lqu->front = lqu->rear = NULL;
}
else {
lqu->front = lqu->front->next;
}
cout << p->data << " ";
free(p);
}
}
return 1;
}
int main() {
initQueue(A);
initQueue(B);
int x, num;
while (1) {
cout << "选择功能(1:新增病人,2:开始会诊,3:退出系统)" << endl;
cin >> x;
switch (x)
{
case 1:
int type;
cout << "选择病人类型(1:轻症,2:重症)" << endl;
cin >> type;
switch (type)
{
case 1:
cout << "(轻症)输入病人编号" << endl;
cin >> num;
enQueue(A, num);
break;
case 2:
cout << "(重症)输入病人编号" << endl;
cin >> num;
enQueue(B, num);
break;
default:
break;
}
break;
case 2:
cout << "开始会诊,顺序为:" << endl;
deQueue(B);
deQueue(A);
cout << endl << "会诊结束" << endl;
case 3:
default:
cout << "已退出系统" << endl;
exit(0);
break;
}
}
return 0;
}
二. 数制的转换
- 问题描述 在日常生活中,常常使用各种编码,如身份证号码、电话号码和邮政编码等,这些编码都是由十进制数组成的。同理,在计算机中采用由若干位二进制数组成的编码来表示字母、符号、汉字和颜色等非数值信息。十进制N和其他进制数的转换是计算机实现计算的基本算法,数值间转换的实质是进行基数的转换。
- 设计要求 设计实现十进制数与二进制数之间的数值转换程序,要求进行某种数值转换后,输入相应的格式正确的数值(可以是混合小数的形式),程序按照设定的算法执行,给出相对应的进制数数值,对于输入数据的合法性可以不做检查。
- 数据结构 本课程设计使用的数据结构是链式队列和链式栈。
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct SNode {
int data;
struct SNode* next;
} SNode, * LinkStack;
Status InitStack(LinkStack& S) {
S = NULL;
return OK;
}
bool StackEmpty(LinkStack S) {
if (!S)
return true;
return false;
}
Status Push(LinkStack& S, int e) {
LinkStack p;
p = new SNode;
if (!p) {
return OVERFLOW;
}
p->data = e;
p->next = S;
S = p;
return OK;
}
Status Pop(LinkStack& S, int& e) {
LinkStack p;
if (!S)
return ERROR;
e = S->data;
p = S;
S = S->next;
delete p;
return OK;
}
void conversion(int N) {
int e;
LinkStack S;
InitStack(S);
while (N)
{
Push(S, N % 2);
N = N / 2;
}
while (!StackEmpty(S))
{
Pop(S, e);
cout << e;
}
}
int main() {
int n, e;
cout << "输入一个非负十进制数:" << endl;
cin >> n;
conversion(n);
return 0;
}
三. 停车场管理
- 问题描述 设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若停车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,停在便道上的第一辆汽车即可开入;当停车场内某辆车要离开时,在其之后开入的车辆必须先退出停车场让路,待该辆车开出大门外,其他车辆再按原次序进入停车场,每辆停放在停车场的车在其离开停车场时必须按其停留的时间长短缴纳费用。试为停车场编制按上述要求进行管理的模拟程序。
- 设计要求 以栈模拟停车场,以队列模拟停车场外的便道,按照从终端读入的输入数据的方式进行模拟管理。输入1,表示车辆到达;输入2,表示车辆离开;输入3,表示显示出停车场内及便道上的停车情况;输入4,表示退出系统。车辆到达操作,需输入汽车牌照号码及到达的时刻;车辆离开操作,需输入汽车在停车场的位置及离开时刻,且应输出汽车在停车场内停留的时间和应缴纳的费用(在便道上停留的时间不收费)。
- 数据结构 本课程设计使用的数据结构是顺序栈和链式队列。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define price 0.5
#define max 2
int flag;
typedef struct time
{
int hour;
int min;
}Time;
typedef struct node
{
long num;
Time reach;
Time leave;
}CarNode;
typedef struct NODE
{
CarNode* stack[10];
int top;
}SeqStackCar;
typedef struct car
{
CarNode* data;
struct car* next;
}QueueNode;
typedef struct Node
{
QueueNode* head;
QueueNode* rear;
}LinkQueueCar;
void InitStack(SeqStackCar* s)
{
int i;
s->top = 0;
for (i = 0; i <= max; i++)
s->stack[s->top] = NULL;
}
int InitQueue(LinkQueueCar* Q)
{
Q->head = (QueueNode*)malloc(sizeof(QueueNode));
if (Q->head != NULL)
{
Q->head->next = NULL;
Q->rear = Q->head;
return 1;
}
else
return -1;
}
void PRINT(CarNode* p, int room)
{
int A1, A2, B1, B2;
printf("\n请输入离开的时间:/**:**/");
scanf("%d:%d", &p->leave.hour, &p->leave.min);
printf("离开车辆的车牌号为:%ld\n", p->num);
printf("其到达时间为: %d:%d\n", p->reach.hour, p->reach.min);
printf("离开时间为: %d:%d\n", p->leave.hour, p->leave.min);
A1 = p->reach.hour;
A2 = p->reach.min;
B1 = p->leave.hour;
B2 = p->leave.min;
printf("应交费用为:%2.1f RMB\n", ((B1 - A1) * 60 + (B2 - A2)) * price);
free(p);
}
void Arrive(SeqStackCar* Enter, LinkQueueCar* W)
{
CarNode* p;
QueueNode* t;
p = (CarNode*)malloc(sizeof(CarNode));
printf("请输入车牌号(例:12345):\n");
scanf("%ld", &p->num);
if (Enter->top < max)
{
Enter->top++;
printf("车辆请停在第%d位置.\n", Enter->top);
printf("请输入到达时间:\n");
scanf("%d:%d", &p->reach.hour, &p->reach.min);
Enter->stack[Enter->top] = p;
}
else
{
printf("该车须在便道等待!.\n");
t = (QueueNode*)malloc(sizeof(QueueNode));
t->data = p;
t->next = NULL;
W->rear->next = t;
W->rear = t;
}
printf("返回主菜单(1.是 0.退出程序)\n");
scanf("%d", &flag);
switch (flag)
{
case 0:
system("cls");
printf("程序已退出\n");
exit(0);
case 1:
system("cls");
}
}
void Leave(SeqStackCar* Enter, SeqStackCar* Temp, LinkQueueCar* W)
{
int i, room;
CarNode* p, * t;
QueueNode* q;
if (Enter->top > 0)
{
while (1)
{
printf("请输入车在车场的位置/1--%d/:\n", Enter->top);
scanf("%d", &room);
if (room >= 1 && room <= Enter->top)
break;
}
while (Enter->top > room)
{
Temp->top++;
Temp->stack[Temp->top] = Enter->stack[Enter->top];
Enter->stack[Enter->top] = NULL;
Enter->top--;
}
p = Enter->stack[Enter->top];
Enter->stack[Enter->top] = NULL;
Enter->top--;
while (Temp->top >= 1)
{
Enter->top++;
Enter->stack[Enter->top] = Temp->stack[Temp->top];
Temp->stack[Temp->top] = NULL;
Temp->top--;
}
PRINT(p, room);
if ((W->head != W->rear) && Enter->top < max)
{
q = W->head->next;
t = q->data;
Enter->top++;
printf("便道的%s号车进入车场第%d位置.\n", t->num, Enter->top);
printf("请输入现在的时间/**:**/:\n");
scanf("%d:%d", &t->reach.hour, &t->reach.min);
W->head->next = q->next;
if (q == W->rear)
W->rear = W->head;
Enter->stack[Enter->top] = t;
free(q);
}
else
printf("便道里没有车.\n");
}
else
printf("车场里没有车.\n");
printf("返回主菜单(1.是 0.退出程序)\n");
scanf("%d", &flag);
switch (flag)
{
case 0:
system("cls");
printf("程序已退出\n");
exit(0);
case 1:
system("cls");
}
}
void List1(SeqStackCar* S)
{
int i;
if (S->top > 0)
{
printf("车场\n");
for (i = 1; i <= S->top; i++)
{
printf("位置%d\t到达时间:%d:%d\t号码:%ld\n", i, S->stack[i]->reach.hour, S->stack[i]->reach.min, S->stack[i]->num);
}
}
else
printf("车场里没有车.\n");
printf("返回主菜单(1.是 0.退出程序)\n");
scanf("%d", &flag);
switch (flag)
{
case 0:
system("cls");
printf("程序已退出\n");
exit(0);
case 1:
system("cls");
}
}
void List2(LinkQueueCar* W)
{
QueueNode* p;
p = W->head->next;
if (W->head != W->rear)
{
printf("等待车辆的号码为:");
while (p != NULL)
{
printf("%ld\n", p->data->num);
p = p->next;
}
}
else
printf("便道里没有车.\n");
printf("返回主菜单(1.是 0.退出程序)\n");
scanf("%d", &flag);
switch (flag)
{
case 0:
system("cls");
printf("程序已退出\n");
exit(0);
case 1:
system("cls");
}
}
void List(SeqStackCar S, LinkQueueCar W)
{
int tag;
printf("1.车场\n");
printf("2.便道\n");
printf("0.返回\n");
scanf("%d", &tag);
system("cls");
switch (tag)
{
case 0:
break;
case 1:
List1(&S);
break;
case 2:
List2(&W);
break;
}
}
int main()
{
SeqStackCar Enter, Temp;
LinkQueueCar Wait;
int ch;
InitStack(&Enter);
InitStack(&Temp);
InitQueue(&Wait);
AA:printf("停车场\n");
printf("\n1.车辆到达\n");
printf("2.车辆离开\n");
printf("3.列表显示\n");
printf("0.退出系统\n");
scanf("%d", &flag);
system("cls");
switch (flag)
{
case 0:
printf("程序已退出\n");
return 0;
case 1:
Arrive(&Enter, &Wait);
goto AA;
case 2:
Leave(&Enter, &Temp, &Wait);
goto AA;
case 3:
List(Enter, Wait);
goto AA;
}
return 0;
}
四. 由遍历确定二叉树
- 问题描述 已知二叉树的先序遍历序列和中序遍历序列,确定二叉树,并遍历这棵二叉树。
- 设计要求 (1) 根据给定的一棵二叉树的先序遍历序列和中序遍历序列,确定这棵二叉树。 (2) 已知二叉树,输出二叉树的先序、中序和后序遍历序列。
- 数据结构 本课程设计使用的数据结构是二叉树,采用二叉链表作为二叉树的存储结构。
#include <iostream>
using namespace std;
typedef struct BiTNode {
int data;
struct BiTNode* lchild, * rchild;
}BiTNode,*BiTree;
void PreOrder(BiTree T) {
if (T != NULL) {
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void InOrder(BiTree T) {
if (T != NULL) {
InOrder(T->lchild);
InOrder(T->rchild);
}
}
void PostOrder(BiTree T) {
if (T != NULL) {
PostOrder(T->lchild);
PostOrder(T->rchild);
}
}
BiTree PreInCreat(int A[], int B[], int l1, int h1, int l2, int h2) {
BiTNode* root = (BiTNode*)malloc(sizeof(BiTNode));
root->data = A[l1];
int llen, rlen;
for (int i = l2; B[i] != root->data; i++) {
llen = i - l2;
rlen = h2 - i;
if (llen) {
root->lchild = PreInCreat(A, B, l1 + 1, l1 + llen, l2, l2 + llen - 1);
}
else {
root->lchild = NULL;
}
if (rlen) {
root->rchild = PreInCreat(A, B, h1 - rlen + 1, h1, h2 - rlen + 1, h2);
}
else {
root->rchild = NULL;
}
}
return root;
}
int main() {
int A[] = {
1,2,3,4,5 };
int B[] = {
2,3,4,1,5 };
PreInCreat(A, B, 1, 5, 1, 5);
return 0;
}