数据结构实验六:简单路径

HUNAN UNIVERSITY

课程实验报

题目:简单路径

学生姓名

学生学号

专业班级

指导老师李晓鸿

完成日期 2 0 1 5年12 月12日

一、需求分析

1.程序的功能

该程序可以通过构建一个图用来表示各个城市之间是否有高速公路连通的关系,可以实现查询两城市间所有路径的功能,如果存在路径则输出。

2.输入的形式

本程序要求用户首先输入一个结点总数,然后输入结点的城市编号,最后输入要查询所有简单路径的两座城市的名称。当用户输入不合法时,提示用户输入有误,并重新输入。输入具体格式如下:请输入城市总数:n(大于零的整数)

请输入输入城市1名称:

请输入输入城市2名称:

请输入输入城市3名称:

......

请输入输入城市n名称:

请输入城市间的高速公路:

请输入两所城市的名称:

3.输出的形式

①若有路径

从城市A到城市B的所有路径如下:

//路径1

//路径2

②若无路径

两城市不连通

4.测试数据

①.正常的输入:

请输入城市总数:4

请输入输入城市1名称:0001

请输入输入城市2名称:0002

请输入输入城市3名称:0003

请输入输入城市4名称:0004

请输入城市间的高速公路:0001 0002

请输入城市间的高速公路:0002 0003

请输入城市间的高速公路:0003 0004

请输入城市间的高速公路:0001 0004

请输入城市间的高速公路:0 0

请输入两所城市的名称:0001 0004

输出:

两城市间的路径为:0001 0002 0003 0004

两城市间的路径为:0001 0004

②.正常的输入:

请输入城市总数:5

请输入输入城市1名称:c1

请输入输入城市2名称:c2

请输入输入城市3名称:c3

请输入输入城市4名称:c4

请输入输入城市5名称:c5

请输入城市间的高速公路:c1 c2

请输入城市间的高速公路:c1 c5

请输入城市间的高速公路:c5 c4

请输入城市间的高速公路:c4 c3

请输入城市间的高速公路:0 0

请输入两所城市的名称:c2 c4

输出:

两城市间的路径为:c2 c1 c5 c4

③.无路径情况:

请输入城市总数:3

请输入输入城市1名称:a

请输入输入城市2名称:b

请输入输入城市3名称:c

请输入城市间的高速公路:a b

请输入城市间的高速公路:0 0

请输入两所城市的名称:a c

输出:

两城市不连通

④.错误的城市个数

请输入城市总数:-1

输入错误重新输入(大于零的整数)

请输入城市总数 2

请输入输入城市1名称:1

请输入输入城市2名称:2

请输入城市间的高速公路:1 2

请输入城市间的高速公路:0 0

请输入两所城市的名称:1 2

输出:

两城市的路径为 1 2

⑤.存在自返路径

请输入城市总数:2

请输入输入城市1名称:上海

请输入输入城市2名称:长沙

请输入城市间的高速公路:上海上海

请输入城市间的高速公路:上海长沙

请输入两所城市的名称:长沙上海

输出:

长沙上海

二、概要设计

1.抽象数据类型

因为各个结点之间是网状结构,那么一个结点会和多个结点连接,因此我们使用图来存储各个结点的信息。同时我们需要一个数据结构来搜索图,该数据结构满足先进后出,所以使用栈来实现。

2.ADT

ADT Stack{

数据对象:D={ a i | a i ∈binNode, i=1,2,...,n, n≥0

数据关系:R1={ | a i-1, a i∈D, i=2,...,n }

约定a n端为栈顶,a1 端为栈底。

若栈中没有元素,则为空栈。

基本操作:

bool push(const BinNode&item);

bool pop(BinNode&it);

bool topValue(BinNode&it);

int length();const;}

ADT Graph{

数据对象:V,R(图是由一个顶点集 V 和一个弧集 R构成的数据结构)

数据关系:Graph = (V,R) VR={|v,w∈V且P(v,w)}

基本操作:int n() =0; // 返回图节点数

int e() =0; //返回图边数

int first(int)=0;//返回该节点的第一条邻边

void setEdge(int v1, int v2)//加边

int next(int, int) =0; //返回下一条邻边

int getMark(int) =0;//有标记吗

void setMark(int, int) =0;//设置标记}

3.算法的基本思想

使用深度优先搜索DFS对图进行遍历,在搜索过程中,每当访问一个顶点V后,DFS就会递归的访问它的所有未被访问的相邻顶点。即先访问点v,把所有与v相关联的边存入栈,弹出栈顶元素,栈顶元素代表的边所关联的另一个顶点就是就是要访问的下一个元素,重复对v的操作;依次类推直到所有元素都被处理完毕。

4程序流程

程序主要由四个步骤组成:

(1)输入城市总数

(2)输入正确的城市编号列表

(3)输入所有的有高速公路直接连接的城市对编号

(4)循环输入需要寻找路径的城市对的编号寻找它们之间的所有简单路径。

三.详细设计

1.物理数据类型

由于边数目未知,所以对于遍历图的时间效率并不清楚,所以可以用邻接表或者邻接矩阵来实现,本实验中使用邻接矩阵。

栈元素未知,用链表来实现栈。

用string保存输入的城市名信息。

2.算法的具体步骤

图的构建——路径的存储——深度优先搜索——栈元素的打印

图的构建:创建一个城市数n*城市数n的二阶矩阵,并且给每一个元素赋值为零。

Graph(int numVert)

{

int i, j;

numVertex = numVert;

numEdge = 0;

mark = new Point[numVert]; // Initialize mark array

for (i = 0; i

mark[i].ViMark = -1;

matrix = (int**) new int*[numVertex]; // Make matrix

for (i = 0; i

matrix[i] = new int[numVertex];

for (i = 0; i< numVertex; i++)//Edges start w/0 weight

for (int j = 0; j

}

路径的存储:将城市v1到城市v2在矩阵中对应的坐标(v1,v2)赋值为1。

void setEdge(int v1, int v2)

{

if (matrix[v1][v2] == 0)

numEdge++;

matrix[v1][v2] = 1;

}

深度优先搜索:在搜索过程中,每当访问一个顶点V后,DFS就会递归的访问它的所有未被访问的相邻顶点。即先访问点v,把所有与v 相关联的边存入栈,弹出栈顶元素,栈顶元素代表的边所关联的另一个顶点就是就是要访问的下一个元素,重复对v的操作;当弹出栈的元素就是我们需要到达的城市v2时,输出整个栈的元素,再将v2的值设置为-1,表示为未访问状态,将v2弹出栈,重复对v的操作;依次类推直到所有元素都被处理完毕。

void DFS(Graph* G, int v1, int origin, int v2, AStack& b, int M[100][100], int D[100], int& count)

{

string Ch;

b.push(G->getVal(v1));

int v;

G->setMark(v1, 1);

if (G->getVal(v1) == G->getVal(v2))

{

for (int i = 0; in(); i++)

for (int j = 0; jn(); j++)

G->setEdge(i, j, M[i][j]);//将路径进栈

cout <<"两城间的路径为:";

b.print();

cout << endl;

b.pop(Ch);//即城市v2出栈

G->setMark(v2, -1);//将v2标记为未被访问

count++;//路线多一条

return;

}

for (int w = G->first(v1); wn(); w = G->next(v1, w))//访问v1所有顶点

{

G->setEdge(w, v1, 0);

if (G->getMark(w) == -1 || w == 5)

{

DFS(G, w, origin, v2, b, M, D, count);

}

}

b.pop(Ch);

G->Find(Ch, v);

G->setMark(v, -1);

}

栈所有元素的打印:新建一个和需要打印栈a长度相同的栈b,栈a 中每一个元素依次出栈进入栈b,直到栈a为空,栈b依次出栈,并且输出每一个元素的值,同时将这些元素进栈a,直到栈b为空。

void print()

{

string Ch;

AStack b(length());

while (pop(Ch))

{

b.push(Ch);

}

while (b.pop(Ch))

{

cout<

push(Ch);

}

}

3.算法的时空分析及改进设想

因为图的邻接矩阵是一个|V|×|V|矩阵,所以邻接矩阵的空间代价为Θ(|V|^2),对于有n个顶点的和E条弧的无向图而言,DFS对每条边分别沿两个方向进行处理,且每个顶点必须被访问一次,所以总的时间代价为Θ(|V|+|E|) 。

综上可知,该程序的时间复杂度为Max(Θ(|V|^2),Θ(|V|+|E|))。

4.输入和输出的格式

①.条件的输入

请输入城市总数:n(大于零的整数)

请输入输入城市1名称:

请输入输入城市2名称:

请输入输入城市3名称:

......

请输入输入城市n名称:

请输入城市间的高速公路:

请输入两所城市的名称:

cout <<"请输入城市总数:";

cin >> n;

if (n <= 0 )

{

cout <<"输入错误重新输入(大于零的整数)"<< endl;

cout <<"请输入城市总数:";

cin >> n;

}

Graph a(n);

for (int i = 0; i

{

cout <<"请输入城市"<< i + 1 <<"编号:";

cin >> Ch;

a.setVal(i, Ch);

}

cout <<"请输入城市之间的高速公路(输入两个0结束输入):";

cin >> Ch1;

cin >> Ch2;

while (Ch1 != "0")

{

a.Find(Ch1, v1);

a.Find(Ch2, v2);

a.setEdge(v1, v2, 10);

a.setEdge(v2, v1, 10);

cout <<"请输入城市之间的公路:";

cin >> Ch1;

cin >> Ch2;

}

②.输入要查找的城市

cout <<"请输入要查找的两个城市:";

cin >> Ch1 >> Ch2;

③.连通情况路径的输出(即上述算法中的栈元素的打印)void print()

{

string Ch;

AStack b(length());

while (pop(Ch))

{

b.push(Ch);

}

while (b.pop(Ch))

{

cout<

push(Ch);

}

}

④.不连通时的输出

if (count == 0)

{

cout <<"两个城市不连通"<< endl;

}

四.测试结果①.正常的输入:

②.正常的输入:

③.无路径情况:

④.错误的城市个数

⑤.存在自返路径

#include

#include

#include

#include

usingnamespace std;

class AStack

{

private:

int size;//栈的大小

int top;//栈中元素的多少

string *listArray;

public:

AStack(int sz = 0)//构建栈

{

size = sz;

top = 0;

listArray = new string[sz];

}

~AStack()//销毁栈

{

delete[]listArray;

}

bool push(const string&item)//压栈

{

if (top == size) returnfalse;//如果栈已满则return false

else

{

listArray[top++] = item;

returntrue;

}

}

bool pop(string& it)//出栈

{

if (top == 0) returnfalse;//如果栈为空栈,则return false

else

{

it = listArray[--top];

returntrue;

}

}

int length()const//获取栈的长度

{

return top;

}

void print()

{

string Ch;

AStack b(length());

while (pop(Ch))

{

b.push(Ch);

}

while (b.pop(Ch))

{

cout<

push(Ch);

}

}

};

class Point

{

public:

string LessonName;

int ViMark;

};

class Graph

{//Implement adjacency matrix

private:

int numVertex, numEdge;//Store number of vertices edges

int **matrix; // Pointer to adjacency matrix

Point *mark; // Pointer to mark array

public:

Graph(int numVert)

{// Make graph w/ numVert vertices

int i, j;

numVertex = numVert;

numEdge = 0;

mark = new Point[numVert]; // Initialize mark array

for (i = 0; i

mark[i].ViMark = -1;

matrix = (int**) newint*[numVertex]; // Make matrix

for (i = 0; i

matrix[i] = newint[numVertex];

for (i = 0; i< numVertex; i++)//Edges start w/0 weight

for (int j = 0; j

}

~Graph()

{

delete[] mark;

for (int i = 0; i

delete[] matrix[i];

delete[] matrix;

}

int n()

{

return numVertex;

}

int e()

{

return numEdge;

}

int first(int v)

{// Return v's first neighbor

int i;

for (i = 0; i

if (matrix[v][i] != 0 && mark[i].ViMark == -1) return i;

return i; // Return n if none

}

int next(int v1, int v2)

{

// Get v1's neighbor after v2

int i;

for (i = v2 + 1; i

if (matrix[v1][i] != 0 && mark[i].ViMark == -1)

{

//cout<<"此时next的i值是:"<

return i;

}

return i;

}

// Set edge (v1, v2) to wgt

void setEdge(int v1, int v2, int wgt)

{

if (matrix[v1][v2] == 0) numEdge++;

matrix[v1][v2] = wgt;

}

void delEdge(int v1, int v2)

{ // Delete edge (v1, v2)

if (matrix[v1][v2] != 0)

numEdge--;

matrix[v1][v2] = 0;

}

int weight(int v1, int v2)

{

return matrix[v1][v2];

}

string getVal(int v)

{

return mark[v].LessonName;

}

int getMark(int v)

{

return mark[v].ViMark;

}

void setVal(int v, string val)

{

mark[v].LessonName = val;

}

void setMark(int v, int Mark)

{

mark[v].ViMark = Mark;

}

void Find(string search, int& v)

{

for (int i = 0; i

{

if (mark[i].LessonName == search)

{

v = i;

return;

}

}

cout <<"路径错误"<< endl;

return;

}

};

void DFS(Graph* G, int v1, int v2, AStack& b, int& count) {

string Ch;

b.push(G->getVal(v1));//将v1边进栈

int v;

G->setMark(v1, 1);

if (G->getVal(v1) == G->getVal(v2))//已经连通的情况

{

cout <<"两城间的路径为:";

b.print();

cout << endl;

b.pop(Ch);//即城市v2出栈

G->setMark(v2, -1);//将v2标记为未被访问

count++;//路线多一条

return;

}

for (int w = G->first(v1); wn(); w = G->next(v1, w))//访问v1所有边{

G->setEdge(w, v1, 0);//访问后G图中此条路径变为0

if (G->getMark(w) == -1 )

{

DFS(G, w, v2, b, count);//访问v1的下一条路径

}

}

b.pop(Ch);//出栈并且将v1边的值给ch

G->Find(Ch, v);//找到v对应的边

G->setMark(v, -1);//设置为未访问

}

int main()

{

int n;

int v1;

int v2;

string Ch;

string Ch1;

string Ch2;

int count = 0;

cout <<"请输入城市总数:";

cin >> n;

if (n <= 0 )

{

cout <<"输入错误重新输入(大于零的整数)"<< endl;

cout <<"请输入城市总数:";

cin >> n;

}

Graph a(n);

for (int i = 0; i

{

cout <<"请输入城市"<< i + 1 <<"编号:";

cin >> Ch;

数据结构实验

实验2 查找算法的实现和应用?实验目的 1. 熟练掌握静态查找表的查找方法; 2. 熟练掌握动态查找表的查找方法; 3. 掌握hash表的技术. ?实验内容 1.用二分查找法对查找表进行查找; 2.建立二叉排序树并对该树进行查找; 3.确定hash函数及冲突处理方法,建立一个hash表并实现查找。 程序代码 #include using namespace std; int main() { int arraay[10]={1,2,3,4,5,6,7,8,9,10}; int binary_search(int a[10],int t); cout<<"Enter the target:"; int target; cin>>target; binary_search(arraay,target); return 0; } int binary_search(int a[10],int t) { int bottom=0,top=9; while(bottom

cout<<"Not present!"; } return 0; } 结果 二叉排序树 #include #include #include using namespace std; typedef int keyType; typedef struct Node { keyType key; struct Node* left; struct Node* right; struct Node* parent; }Node,*PNode; void inseart(PNode* root, keyType key) { PNode p = (PNode)malloc(sizeof(Node)); p -> key = key;

数据结构实验报告格式

《数据结构课程实验》大纲 一、《数据结构课程实验》的地位与作用 “数据结构”是计算机专业一门重要的专业技术基础课程,是计算机专业的一门核心的关键性课程。本课程较系统地介绍了软件设计中常用的数据结构以及相应的存储结构和实现算法,介绍了常用的多种查找和排序技术,并做了性能分析和比较,内容非常丰富。本课程的学习将为后续课程的学习以及软件设计水平的提高打下良好的基础。 由于以下原因,使得掌握这门课程具有较大的难度: (1)内容丰富,学习量大,给学习带来困难; (2)贯穿全书的动态链表存储结构和递归技术是学习中的重点也是难点; (3)所用到的技术多,而在此之前的各门课程中所介绍的专业性知识又不多,因而加大了学习难度; (4)隐含在各部分的技术和方法丰富,也是学习的重点和难点。 根据《数据结构课程》课程本身的技术特性,设置《数据结构课程实验》实践环节十分重要。通过实验实践内容的训练,突出构造性思维训练的特征, 目的是提高学生组织数据及编写大型程序的能力。实验学时为18。 二、《数据结构课程实验》的目的和要求 不少学生在解答习题尤其是算法设计题时,觉得无从下手,做起来特别费劲。实验中的内容和教科书的内容是密切相关的,解决题目要求所需的各种技术大多可从教科书中找到,只不过其出现的形式呈多样化,因此需要仔细体会,在反复实践的过程中才能掌握。 为了帮助学生更好地学习本课程,理解和掌握算法设计所需的技术,为整个专业学习打好基础,要求运用所学知识,上机解决一些典型问题,通过分析、设计、编码、调试等各环节的训练,使学生深刻理解、牢固掌握所用到的一些技术。数据结构中稍微复杂一些的算法设计中可能同时要用到多种技术和方法,如算法设计的构思方法,动态链表,算法的编码,递归技术,与特定问题相关的技术等,要求重点掌握线性链表、二叉树和树、图结构、数组结构相关算法的设计。在掌握基本算法的基础上,掌握分析、解决实际问题的能力。 三、《数据结构课程实验》内容 课程实验共18学时,要求完成以下六个题目: 实习一约瑟夫环问题(2学时)

数据结构实验

数据结构实验指导书

实验一线性表的顺序存储结构 一、实验学时 4学时 二、背景知识:顺序表的插入、删除及应用。 三、目的要求: 1.掌握顺序存储结构的特点。 2.掌握顺序存储结构的常见算法。 四、实验内容 1.从键盘随机输入一组整型元素序列,建立顺序表。(注意:不可将元素个数和元素值写死在程序中) 2.实现该顺序表的遍历(也即依次打印出每个数据元素的值)。 3.在该顺序表中顺序查找某一元素,如果查找成功返回1,否则返回0。 4.实现把该表中某个数据元素删除。 5.实现在该表中插入某个数据元素。 6.实现两个线性表的归并(仿照课本上P26 算法2.7)。 7. 编写一个主函数,调试上述6个算法。 五、实现提示 1.存储定义 #include #include #define MAXSIZE 100 //表中元素的最大个数

typedef int ElemType;//元素类型 typedef struct list{ ElemType *elem;//静态线性表 int length; //表的实际长度 int listsize; //表的存储容量 }SqList;//顺序表的类型名 2.建立顺序表时可利用随机函数自动产生数据。 3.为每个算法功能建立相应的函数分别调试,最后在主函数中调用它们。 六、注意问题 插入、删除元素时对于元素合法位置的判断。 七、测试过程 1.先从键盘输入元素个数,假设为6。 2.从键盘依次输入6个元素的值(注意:最好给出输入每个元素的提示,否则除了你自己知道之外,别人只见光标在闪却不知道要干什么),假设是:10,3,8,39,48,2。 3.遍历该顺序表。 4.输入待查元素的值例如39(而不是待查元素的位置)进行查找,因为它在表中所以返回1。假如要查找15,因为它不存在,所以返回0。 5.输入待删元素的位置将其从表中删掉。此处需要注意判断删位置是否合法,若表中有n个元素,则合法的删除位

数据结构实验答案1

重庆文理学院软件工程学院实验报告册 专业:_____软件工程__ _ 班级:_____软件工程2班__ _ 学号:_____201258014054 ___ 姓名:_____周贵宇___________ 课程名称:___ 数据结构 _ 指导教师:_____胡章平__________ 2013年 06 月 25 日

实验序号 1 实验名称实验一线性表基本操作实验地点S-C1303 实验日期2013年04月22日 实验内容1.编程实现在顺序存储的有序表中插入一个元素(数据类型为整型)。 2.编程实现把顺序表中从i个元素开始的k个元素删除(数据类型为整型)。 3.编程序实现将单链表的数据逆置,即将原表的数据(a1,a2….an)变成 (an,…..a2,a1)。(单链表的数据域数据类型为一结构体,包括学生的部分信息:学号,姓名,年龄) 实验过程及步骤1. #include #include #include #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define ElemType int #define MAXSIZE 100 /*此处的宏定义常量表示线性表可能达到的最大长度*/ typedef struct

{ ElemType elem[MAXSIZE]; /*线性表占用的数组空间*/ int last; /*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/ }SeqList; #include "common.h" #include "seqlist.h" void px(SeqList *A,int j); void main() { SeqList *l; int p,q,r; int i; l=(SeqList*)malloc(sizeof(SeqList)); printf("请输入线性表的长度:"); scanf("%d",&r); l->last = r-1; printf("请输入线性表的各元素值:\n"); for(i=0; i<=l->last; i++) { scanf("%d",&l->elem[i]); } px(l,i); printf("请输入要插入的值:\n");

数据结构实验报告

数据结构实验报告 一.题目要求 1)编程实现二叉排序树,包括生成、插入,删除; 2)对二叉排序树进行先根、中根、和后根非递归遍历; 3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。 4)分别用二叉排序树和数组去存储一个班(50人以上)的成员信息(至少包括学号、姓名、成绩3项),对比查找效率,并说明在什么情况下二叉排序树效率高,为什么? 二.解决方案 对于前三个题目要求,我们用一个程序实现代码如下 #include #include #include #include "Stack.h"//栈的头文件,没有用上 typedefintElemType; //数据类型 typedefint Status; //返回值类型 //定义二叉树结构 typedefstructBiTNode{ ElemType data; //数据域 structBiTNode *lChild, *rChild;//左右子树域 }BiTNode, *BiTree; intInsertBST(BiTree&T,int key){//插入二叉树函数 if(T==NULL) { T = (BiTree)malloc(sizeof(BiTNode)); T->data=key; T->lChild=T->rChild=NULL; return 1; } else if(keydata){ InsertBST(T->lChild,key); } else if(key>T->data){ InsertBST(T->rChild,key); } else return 0; } BiTreeCreateBST(int a[],int n){//创建二叉树函数 BiTreebst=NULL; inti=0; while(i

数据结构_实验六_报告

实验报告 实验六图的应用及其实现 一、实验目的 1.进一步功固图常用的存储结构。 2.熟练掌握在图的邻接表实现图的基本操作。 3.理解掌握AOV网、AOE网在邻接表上的实现以及解决简单的应用问题。 二、实验内容 一>.基础题目:(本类题目属于验证性的,要求学生独立完成) [题目一]:从键盘上输入AOV网的顶点和有向边的信息,建立其邻接表存储结构,然后对该图拓扑排序,并输出拓扑序列. 试设计程序实现上述AOV网 的类型定义和基本操作,完成上述功能。 [题目二]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。 测试数据:教材图7.29 【题目五】连通OR 不连通 描述:给定一个无向图,一共n个点,请编写一个程序实现两种操作: D x y 从原图中删除连接x,y节点的边。 Q x y 询问x,y节点是否连通 输入 第一行两个数n,m(5<=n<=40000,1<=m<=100000) 接下来m行,每行一对整数 x y (x,y<=n),表示x,y之间有边相连。保证没有重复的边。 接下来一行一个整数 q(q<=100000) 以下q行每行一种操作,保证不会有非法删除。 输出 按询问次序输出所有Q操作的回答,连通的回答C,不连通的回答D 样例输入

3 3 1 2 1 3 2 3 5 Q 1 2 D 1 2 Q 1 2 D 3 2 Q 1 2 样例输出 C C D 【题目六】 Sort Problem An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not. 【Input】 Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n<= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. 1 <= m <= 100. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input. 【Output】 For each problem instance, output consists of one line. This line should be one of the following three: Sorted sequence determined: y y y… y. Sorted sequence cannot be determined. Inconsistency found.

数据结构实验报告全集

数据结构实验报告全集 实验一线性表基本操作和简单程序 1.实验目的 (1)掌握使用Visual C++ 6.0上机调试程序的基本方法; (2)掌握线性表的基本操作:初始化、插入、删除、取数据元素等运算在顺序存储结构和链表存储结构上的程序设计方法。 2.实验要求 (1)认真阅读和掌握和本实验相关的教材内容。 (2)认真阅读和掌握本章相关内容的程序。 (3)上机运行程序。 (4)保存和打印出程序的运行结果,并结合程序进行分析。 (5)按照你对线性表的操作需要,重新改写主程序并运行,打印出文件清单和运行结果 实验代码: 1)头文件模块 #include iostream.h>//头文件 #include//库头文件-----动态分配内存空间 typedef int elemtype;//定义数据域的类型 typedef struct linknode//定义结点类型 { elemtype data;//定义数据域 struct linknode *next;//定义结点指针 }nodetype; 2)创建单链表

nodetype *create()//建立单链表,由用户输入各结点data域之值,//以0表示输入结束 { elemtype d;//定义数据元素d nodetype *h=NULL,*s,*t;//定义结点指针 int i=1; cout<<"建立一个单链表"<> d; if(d==0) break;//以0表示输入结束 if(i==1)//建立第一个结点 { h=(nodetype*)malloc(sizeof(nodetype));//表示指针h h->data=d;h->next=NULL;t=h;//h是头指针 } else//建立其余结点 { s=(nodetype*) malloc(sizeof(nodetype)); s->data=d;s->next=NULL;t->next=s; t=s;//t始终指向生成的单链表的最后一个节点

数据结构实验报告

姓名: 学号: 班级: 2010年12月15日

实验一线性表的应用 【实验目的】 1、熟练掌握线性表的基本操作在顺序存储和链式存储上的实现。、; 2、以线性表的各种操作(建立、插入、删除、遍历等)的实现为重点; 3、掌握线性表的动态分配顺序存储结构的定义和基本操作的实现; 4、通过本章实验帮助学生加深对C语言的使用(特别是函数的参数调用、指针类型的 应用和链表的建立等各种基本操作)。 【实验内容】 约瑟夫问题的实现:n只猴子要选猴王,所有的猴子按1,2,…,n编号围坐一圈,从第一号开始按1,2…,m报数,凡报到m号的猴子退出圈外,如此次循环报数,知道圈内剩下一只猴子时,这个猴子就是猴王。编写一个程序实现上述过程,n和m由键盘输入。【实验要求】 1、要求用顺序表和链表分别实现约瑟夫问题。 2、独立完成,严禁抄袭。 3、上的实验报告有如下部分组成: ①实验名称 ②实验目的 ③实验内容:问题描述:数据描述:算法描述:程序清单:测试数据 算法: #include #include typedef struct LPeople { int num; struct LPeople *next; }peo; void Joseph(int n,int m) //用循环链表实现 { int i,j; peo *p,*q,*head; head=p=q=(peo *)malloc(sizeof(peo)); p->num=0;p->next=head; for(i=1;inum=i;q->next=p;p->next=head; } q=p;p=p->next; i=0;j=1; while(i

数据结构实验报告模板

2009级数据结构实验报告 实验名称:约瑟夫问题 学生姓名:李凯 班级:21班 班内序号:06 学号:09210609 日期:2010年11月5日 1.实验要求 1)功能描述:有n个人围城一个圆圈,给任意一个正整数m,从第一个人开始依次报数,数到m时则第m个人出列,重复进行,直到所有人均出列为止。请输出n个人的出列顺序。 2)输入描述:从源文件中读取。 输出描述:依次从显示屏上输出出列顺序。 2. 程序分析 1)存储结构的选择 单循环链表 2)链表的ADT定义 ADT List{ 数据对象:D={a i|a i∈ElemSet,i=1,2,3,…n,n≧0} 数据关系:R={< a i-1, a i>| a i-1 ,a i∈D,i=1,2,3,4….,n} 基本操作: ListInit(&L);//构造一个空的单链表表L ListEmpty(L); //判断单链表L是否是空表,若是,则返回1,否则返回0. ListLength(L); //求单链表L的长度 GetElem(L,i);//返回链表L中第i个数据元素的值; ListSort(LinkList&List) //单链表排序 ListClear(&L); //将单链表L中的所有元素删除,使单链表变为空表 ListDestroy(&L);//将单链表销毁 }ADT List 其他函数: 主函数; 结点类; 约瑟夫函数 2.1 存储结构

[内容要求] 1、存储结构:顺序表、单链表或其他存储结构,需要画示意图,可参考书上P59 页图2-9 2.2 关键算法分析 结点类: template class CirList;//声明单链表类 template class ListNode{//结点类定义; friend class CirList;//声明链表类LinkList为友元类; Type data;//结点的数据域; ListNode*next;//结点的指针域; public: ListNode():next(NULL){}//默认构造函数; ListNode(const Type &e):data(e),next(NULL){}//构造函数 Type & GetNodeData(){return data;}//返回结点的数据值; ListNode*GetNodePtr(){return next;}//返回结点的指针域的值; void SetNodeData(Type&e){data=e;}//设置结点的数据值; void SetNodePtr(ListNode*ptr){next=ptr;} //设置结点的指针值; }; 单循环链表类: templateclass CirList { ListNode*head;//循环链表头指针 public: CirList(){head=new ListNode();head->next=head;}//构造函数,建立带头节点的空循环链表 ~CirList(){CirListClear();delete head;}//析构函数,删除循环链表 void Clear();//将线性链表置为空表 void AddElem(Type &e);//添加元素 ListNode *GetElem(int i)const;//返回单链表第i个结点的地址 void CirListClear();//将循环链表置为空表 int Length()const;//求线性链表的长度 ListNode*ListNextElem(ListNode*p=NULL);//返回循环链表p指针指向节点的直接后继,若不输入参数,则返回头指针 ListNode*CirListRemove(ListNode*p);//在循环链表中删除p指针指向节点的直接后继,且将其地址通过函数值返回 CirList&operator=(CirList&List);//重载赋

数据结构第六章实验

#include #include #include typedef struct{ unsigned int weight; unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char * *HuffmanCode; /*void Select(HuffmanTree &HT,int n,int &s1,int &s2) { s1=1;int j; for(j=1;j<=n;j++) { while(HT[j].parent==0) { if(HT[s1].weight>HT[j].weight) s1=j; } } HT[s1].parent=1; if(s1!=1)s2=1;else s2=2; for( j=1;j<=n;j++) { while(HT[j].parent==0) { if(HT[s2].weight>HT[j].weight) s2=j; } } }错误,未查出原因*/ int min(HuffmanTree t,int i) { int j,flag; unsigned int k; for(j=1;j<=i;j++) if(t[j].weight

数据结构实验

长春大学计算机学院网络工程专业 数据结构实验报告 实验名称:实验二栈和队列的操作与应用 班级:网络14406 姓名:李奎学号:041440624 实验地点:日期: 一、实验目的: 1.熟练掌握栈和队列的特点。 2.掌握栈的定义和基本操作,熟练掌握顺序栈的操作及应用。 3.掌握链队的入队和出队等基本操作。 4.加深对栈结构和队列结构的理解,逐步培养解决实际问题的编程能力。 二、实验内容、要求和环境: 注:将完成的实验报告重命名为:班级+学号+姓名+(实验二),(如:041340538张三(实验二)),发邮件到:ccujsjzl@https://www.360docs.net/doc/c215799500.html,。提交时限:本次实验后24小时之内。 阅读程序,完成填空,并上机运行调试。 1、顺序栈,对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数 (1)文件SqStackDef. h 中实现了栈的顺序存储表示 #define STACK_INIT_SIZE 10 /* 存储空间初始分配量*/ #define STACKINCREMENT 2 /* 存储空间分配增量*/ typedef struct SqStack { SElemType *base; /* 在栈构造之前和销毁之后,base 的值为NULL */ SElemType *top; /* 栈顶指针*/ int stacksize; /* 当前已分配的存储空间,以元素为单位*/ }SqStack; /* 顺序栈*/ (2)文件SqStackAlgo.h 中实现顺序栈的基本操作(存储结构由SqStackDef.h 定义) Status InitStack(SqStack &S) { /* 构造一个空栈S */ S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base) exit(OVERFLOW); /* 存储分配失败*/ S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; } int StackLength(SqStack S) { // 返回S 的元素个数,即栈的长度, 编写此函数

数据结构实验六

洛阳理工学院实验报告

附:源程序: #include #include #include #define ENDKEY -1 #define NULL 0 #define OK 1 typedef struct node { int key; struct node *lchild,*rchild; }BSTNode, *BSTree; int InsertBST(BSTree *bst,int key) //插入函数{ BSTree s; if (*bst==NULL) { s=(BSTree)malloc(sizeof(BSTNode)); s->key=key; s->lchild=NULL; s->rchild=NULL; *bst=s; return OK; } else if(key<=(*bst)->key)

{ InsertBST(&((*bst)->lchild),key); return OK; } else if(key>(*bst)->key) { InsertBST(&((*bst)->rchild),key); return OK; } } void CreateBST(BSTree *bst) { int key; *bst=NULL; scanf("%d", &key); while (key!=ENDKEY) { InsertBST(bst, key); scanf("%d", &key); } } BSTree SearchBST(BSTree bst, int key) { if(!bst) return NULL; else if(bst->key==key) return bst; //查找成功 else if(bst->key>key) return SearchBST(bst->lchild,key); else return SearchBST(bst->rchild,key);

数据结构实验六 图的应用及其实现

实验六图的应用及其实现 一、实验目的 1.进一步功固图常用的存储结构。 2.熟练掌握在图的邻接表实现图的基本操作。 3.理解掌握AOE网在邻接表上的实现及解决简单的应用问题。 二、实验内容 [题目]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。 三、实验步骤 (一)、数据结构与核心算法的设计描述 本实验题目是基于图的基本操作以及邻接表的存储结构之上,着重拓扑排序算法的应用,做好本实验的关键在于理解拓扑排序算法的实质及其代码的实现。 (二)、函数调用及主函数设计 以下是头文件中数据结构的设计和相关函数的声明: typedef struct ArcNode // 弧结点 { int adjvex; struct ArcNode *nextarc; InfoType info; }ArcNode; typedef struct VNode //表头结点 { VertexType vexdata; ArcNode *firstarc; }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct //图的定义 { AdjList vertices; int vexnum,arcnum; int kind; }MGraph; typedef struct SqStack //栈的定义 { SElemType *base; SElemType *top; int stacksize;

}SqStack; int CreateGraph(MGraph &G);//AOE网的创建 int CriticalPath(MGraph &G);//输出关键路径 (三)、程序调试及运行结果分析 (四)、实验总结 在做本实验的过程中,拓扑排具体代码的实现起着很重要的作用,反复的调试和测试占据着实验大量的时间,每次对错误的修改都加深了对实验和具体算法的理解,自己的查错能力以及其他各方面的能力也都得到了很好的提高。最终实验结果也符合实验的预期效果。 四、主要算法流程图及程序清单 1、主要算法流程图: 2、程序清单: 创建AOE网模块: int CreateGraph(MGraph &G) //创建有向网 { int i,j,k,Vi,Vj; ArcNode *p; cout<<"\n请输入顶点的数目、边的数目"<

数据结构实验报告图实验

邻接矩阵的实现 1. 实验目的 (1)掌握图的逻辑结构 (2)掌握图的邻接矩阵的存储结构 (3)验证图的邻接矩阵存储及其遍历操作的实现2. 实验内容 (1)建立无向图的邻接矩阵存储 (2)进行深度优先遍历 (3)进行广度优先遍历3.设计与编码MGraph.h #ifndef MGraph_H #define MGraph_H const int MaxSize = 10; template class MGraph { public: MGraph(DataType a[], int n, int e); ~MGraph(){ void DFSTraverse(int v); void BFSTraverse(int v); private: DataType vertex[MaxSize]; int arc[MaxSize][MaxSize]; }

int vertexNum, arcNum; }; #endif MGraph.cpp #include using namespace std; #include "MGraph.h" extern int visited[MaxSize]; template MGraph::MGraph(DataType a[], int n, int e) { int i, j, k; vertexNum = n, arcNum = e; for(i = 0; i < vertexNum; i++) vertex[i] = a[i]; for(i = 0;i < vertexNum; i++) for(j = 0; j < vertexNum; j++) arc[i][j] = 0; for(k = 0; k < arcNum; k++) { cout << "Please enter two vertexs number of edge: " cin >> i >> j; arc[i][j] = 1; arc[j][i] = 1; } }

数据结构实验报告及心得体会

2011~2012第一学期数据结构实验报告 班级:信管一班 学号:201051018 姓名:史孟晨

实验报告题目及要求 一、实验题目 设某班级有M(6)名学生,本学期共开设N(3)门课程,要求实现并修改如下程序(算法)。 1. 输入学生的学号、姓名和 N 门课程的成绩(输入提示和输出显示使用汉字系统), 输出实验结果。(15分) 2. 计算每个学生本学期 N 门课程的总分,输出总分和N门课程成绩排在前 3 名学 生的学号、姓名和成绩。 3. 按学生总分和 N 门课程成绩关键字升序排列名次,总分相同者同名次。 二、实验要求 1.修改算法。将奇偶排序算法升序改为降序。(15分) 2.用选择排序、冒泡排序、插入排序分别替换奇偶排序算法,并将升序算法修改为降序算法;。(45分)) 3.编译、链接以上算法,按要求写出实验报告(25)。 4. 修改后算法的所有语句必须加下划线,没做修改语句保持按原样不动。 5.用A4纸打印输出实验报告。 三、实验报告说明 实验数据可自定义,每种排序算法数据要求均不重复。 (1) 实验题目:《N门课程学生成绩名次排序算法实现》; (2) 实验目的:掌握各种排序算法的基本思想、实验方法和验证算法的准确性; (3) 实验要求:对算法进行上机编译、链接、运行; (4) 实验环境(Windows XP-sp3,Visual c++); (5) 实验算法(给出四种排序算法修改后的全部清单); (6) 实验结果(四种排序算法模拟运行后的实验结果); (7) 实验体会(文字说明本实验成功或不足之处)。

三、实验源程序(算法) Score.c #include "stdio.h" #include "string.h" #define M 6 #define N 3 struct student { char name[10]; int number; int score[N+1]; /*score[N]为总分,score[0]-score[2]为学科成绩*/ }stu[M]; void changesort(struct student a[],int n,int j) {int flag=1,i; struct student temp; while(flag) { flag=0; for(i=1;ia[i+1].score[j]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; flag=1; } for(i=0;ia[i+1].score[j]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; flag=1;

数据结构实验四五六

数据结构实验 实验四、图遍历的演示。 【实验学时】5学时 【实验目的】 (1)掌握图的基本存储方法。 (2)熟练掌握图的两种搜索路径的遍历方法。 【问题描述】 很多涉及图上操作的算法都是以图的遍历操作为基础的。试写一个程序,演示连通的无向图上,遍历全部结点的操作。 【基本要求】 以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。 【测试数据】 教科书图7.33。暂时忽略里程,起点为北京。 【实现提示】 设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。通过输入图的全部边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制。注意,生成树的边是有向边,端点顺序不能颠倒。

【选作内容】 (1)借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。(2)以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。 (3)正如习题7。8提示中分析的那样,图的路径遍历要比结点遍历具有更为广泛的应用。再写一个路径遍历算法,求出从北京到广州中途不过郑州的所有简单路径及其里程。 【源程序】 #include #include #include #define MAX_VERTEX_NUM 20 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define TRUE 1 #define OK 1 #define FALSE 0 #define ERROR 0 #define OVERFLOW -2 typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网} bool visited[MAX_VERTEX_NUM];

数据结构实验六 堆栈实验

一,实验题目 实验六堆栈实验 设计算法,把一个十进制整数转化为二进制数输出。 二,问题分析 本程序要求将一个十进制整数转化为二进制数输出。完成此功能所要解决的问题是熟练掌握和运用入栈和出栈操作,实现十进制整数转化为二进制数。 (1)数据的输入形式和输入值得范围:输入的是一个十进制整数,且其为正整数。 (2)结果的输出形式:输出的是一个二进制整数 (3)测试数据:1)9 2)4500 三,概要设计 1.为了实现上述程序功能,需要: 构造一个空的顺序栈s 将十进制整数除以2的余数入栈 将余数按顺序出栈 2.本程序包含7个函数: 1)主函数main(); 2)顺序栈判栈空函数stackempty(seqstack *s) 3)顺序栈置空栈函数seqstack *initstack(seqstack *s) 4)顺序栈入栈函数push(seqstack *s,int x) 5)顺序栈出栈函数pop(seqstack *s) 6)顺序栈取栈顶元素函数gettop(seqstack *s) 7)将十进制数转换为二进制数函数setnum(int num) 各函数间关系如下:

四,详细设计 1,顺序表的结构类型定义: typedef struct{ int data[maxlen]; int top; }seqstack; 2,顺序栈入栈函数的伪代码: void push(seqstack *s,int x){ if(s->top<=maxlen-1&&s->top>=-1){ s->top++; s->data[s->top]=x;} else printf("error");} 3,顺序栈出栈函数的伪代码: void pop(seqstack *s){ if(s->top>=0) s->top--; else printf("error"); } 4,将十进制数转换为二进制数函数伪代码: void setnum(int num){ seqstack s; initstack(&s); while(num){ int k=num%2; push(&s,k); num=num/2;} while(!stackempty(&s)){ int x=gettop(&s); printf("%d",x); pop(&s); } } 五,源代码 #include "stdio.h" #define maxlen 100 typedef struct{ //定义顺序栈的结构类型 int data[maxlen]; int top; }seqstack; int stackempty(seqstack *s){ //顺序栈判栈空算法if(s->top>=0) return 0; else return 1; } seqstack *initstack(seqstack *s){ //顺序栈置空栈算法s->top=-1; return s; }

数据结构实验报告图实验

图实验 一,邻接矩阵的实现 1.实验目的 (1)掌握图的逻辑结构 (2)掌握图的邻接矩阵的存储结构 (3)验证图的邻接矩阵存储及其遍历操作的实现 2.实验内容 (1)建立无向图的邻接矩阵存储 (2)进行深度优先遍历 (3)进行广度优先遍历 3.设计与编码 #ifndef MGraph_H #define MGraph_H const int MaxSize = 10; template class MGraph { public: MGraph(DataType a[], int n, int e); ~MGraph(){ } void DFSTraverse(int v); void BFSTraverse(int v); private: DataType vertex[MaxSize]; int arc[MaxSize][MaxSize]; int vertexNum, arcNum; }; #endif #include using namespace std; #include "" extern int visited[MaxSize]; template MGraph::MGraph(DataType a[], int n, int e) { int i, j, k; vertexNum = n, arcNum = e; for(i = 0; i < vertexNum; i++) vertex[i] = a[i]; for(i = 0;i < vertexNum; i++) for(j = 0; j < vertexNum; j++) arc[i][j] = 0;

相关文档
最新文档