树的应用 (2学时)
1、实验目的
通过本实验掌握二叉的建立和递归遍历、非递归遍历算法,了解二叉树在实际中的应用并熟练运用二叉树解决实际问题。
2、实验内容
根据前序遍历的顺序建立一棵二叉树,并根据遍历规则遍历二叉树。
打印输出。
3、实验要求
(1)根据前序遍历的顺序创建一棵二叉树;
()对二叉树进行前序、中序、后序遍历。
收获:会了非递归进行的三种遍历
//15070642肖龙
#include<bits/stdc++.h>
using namespace std;
struct bintree
{
char data;
bool flag;//判断这个节点的右子树的值是不是输出了
bintree *lchild,*rchild;
};
//7.13
//采用递归和非递归两种方法求二叉树的节点的个数
//都用前序遍历吧;
int ans;
bintree* creat()
{
char ch;
bintree* t;
if((ch = getchar()) == '#')
{
t = NULL;
}
else
{
t = new bintree;
t -> data = ch;
t -> lchild = creat();
t -> rchild = creat();
}
return t;
}
void pre_orders(bintree* root)//递归遍历前序
{
if(root == NULL)
return ;
else
{
ans ++;
cout << root -> data ;
pre_orders(root -> lchild);
pre_orders(root -> rchild);
}
}
void pre_orderss(bintree* root)//非递归遍历前序
{
stack<bintree*>s;
while( root || s.size() )
{
if(root)
{
ans ++;
cout << root -> data;
s.push(root);
root = root -> lchild;
}
else
{
root = s.top();
s.pop();
root = root -> rchild;
}
}
}
void in_orders(bintree* root)
{
if(root == NULL)
return ;
in_orders(root -> lchild);
cout << root -> data;
in_orders(root -> rchild);
}
void in_orderss(bintree* root)
{
stack<bintree*>s;
while(root || s.size() )
{
if(root)
{
s.push(root);
root = root -> lchild;
}
else
{
root = s.top();
s.pop();
cout << root -> data ;
root = root -> rchild;
}
}
}
void post_orders(bintree* root)
{
if(root == NULL)
return ;
post_orders(root -> lchild);
post_orders(root -> rchild);
cout << root -> data;
}
void post_orderss(bintree* root)
{
stack<bintree*>s;
while(root || s.size())
{
if(root)
{
root -> flag = false;
s.push(root);
root = root -> lchild;
}
else
{
bintree* temp = s.top();
if(temp -> flag)
{
root = temp;
s.pop();
cout << root -> data;
root = NULL;
}
else
{
root = temp;
root -> flag = true;
root = root -> rchild;
}
}
}
}
void Travel(bintree* root)
{
queue<bintree*>q;
q.push(root);
while( ! q.empty() )
{
bintree* temp = q.front();
q.pop();
cout << temp -> data ;
if(temp -> lchild)
q.push(temp -> lchild);
if(temp -> rchild)
q.push(temp -> rchild);
}
}
int main()
{
bintree* root;
cout << "要求构建一棵深度为3的满二叉树 && 完成习题7.13求出数的节点个数" << endl;
cout << "用前序创建二叉树" << endl;
root = creat();
cout << "用递归进行前序遍历并计算节点的个数:" << endl;
ans = 0;
pre_orders(root);
cout << endl;
cout <<"节点个数为" << ans << endl;
ans = 0;
cout << "用非递归进行前序遍历并计算节点个数:"<< endl;
pre_orderss(root);
cout << endl;
cout << "非递归的节点个数为:" << ans << endl;
cout << "用递归进行中序遍历和后序遍历"<<endl;
in_orders(root);
cout << endl;
post_orders(root);
cout << endl;
cout << "非递归实现中序和后序遍历"<< endl;
in_orderss(root);
cout << endl;
post_orderss(root);
cout << endl;
cout << "用层次遍历玩玩:应该就是ABCDEFG哈"<< endl;
Travel(root);
cout << endl;
return 0;
}
//运行结果
//要求构建一棵深度为3的满二叉树 && 完成习题7.13求出数的节点个数
//用前序创建二叉树
//ABD##E##CF##G##
//用递归进行前序遍历并计算节点的个数:
//ABDECFG
//节点个数为7
//用非递归进行前序遍历并计算节点个数:
//ABDECFG
//非递归的节点个数为:7
//用递归进行中序遍历和后序遍历
//DBEAFCG
//DEBFGCA
//非递归实现中序和后序遍历
//DBEAFCG
//DEBFGCA
//用层次遍历玩玩:应该就是ABCDEFG哈
//ABCDEFG
//
//Process returned 0 (0x0) execution time : 35.166 s
//Press any key to continue.
图的应用(2学时)
1、实验目的
通过本实验掌握图的存储结构与基本运算以及图的深度优先遍历和 图的广度优先遍历算法在实际问题中的应用。
2、实验内容
按照邻接表对图进行创建,并运用图的深度优先遍历和 图的广度优先遍历算法对所创建的无向图进行遍历。
3、实验要求
(1)按照邻接表创建图的结构体;
(2)创建一个无向图;
(3)对创建好的图进行深度优先或广度优先遍历。
收获:对邻接表的创建,遍历#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 10;
bool vis[maxn];
struct edgeNode
{
int adjvex;
edgeNode *next;
};
struct vertexNode
{
int vertex;
edgeNode *firstedge;
};
struct linkgraph
{
vertexNode adjlist[maxn];
int n,e;//顶点数和边数
};
linkgraph* Creat(linkgraph *g)//创建无向图的邻接表
{
scanf("%d%d",&g -> n,&g -> e);
for(int i = 0 ; i < g -> n ; ++ i)
{
g -> adjlist[i].vertex = i;
g -> adjlist[i].firstedge = NULL;
}
for(int i = 1; i <= g -> e; ++ i)
{
int a,b;
scanf("%d%d",&a,&b);
edgeNode *t = new edgeNode;//前插
t -> adjvex = b;
t -> next = g -> adjlist[a].firstedge;
(g -> adjlist[a] ).firstedge = t;
edgeNode *temp = new edgeNode;
temp -> adjvex = a;
temp -> next = g -> adjlist[b].firstedge;
g -> adjlist[b].firstedge = temp;
}
return g;
}
void dfs(linkgraph *g ,int i)//i代表头节点
{
printf("%d ",g -> adjlist[i].vertex);
vis[i] = true;
edgeNode* p = g -> adjlist[i].firstedge;
while(p)
{
if(!vis[p -> adjvex])
{
dfs(g,p -> adjvex);
}
p = p -> next;
}
}
void dfstraverse(linkgraph *g)//dfs调用
{
memset(vis,false,sizeof(vis));
printf("深度优先:\n");
for(int i = 0 ; i < g -> n ; ++ i)
{
if(!vis[i])
dfs(g,i);
}
printf("\n");
}
void bfs(linkgraph *g,int i)
{
printf("%d ",g -> adjlist[i].vertex);
queue<int>q;
q.push(i);
vis[i] = true;
while(!q.empty())
{
int t = q.front();
q.pop();
edgeNode *p = g -> adjlist[t].firstedge;
while(p)
{
if(!vis[p -> adjvex])
{
q.push(p -> adjvex);
printf("%d ",p -> adjvex);
vis[p -> adjvex] = true;
}
p = p -> next;
}
}
}
void bfstraverse(linkgraph *g)//输出分块
{
int cnt = 1;//记录联通块的个数
memset(vis,false,sizeof(vis));
for(int i = 0 ; i < g -> n ; ++ i)
{
if(!vis[i])
{
bfs(g,i);
printf("\n");
}
}
printf("联通块的个数是:%d\n",cnt);
}
int main()
{
linkgraph *g;
g = new linkgraph;
g = Creat(g);
dfstraverse(g);//深度优先
bfstraverse(g);
return 0;
}
//运行结果:
//4 3
//0 1
//1 2
//2 3
//深度优先:
//0 1 2 3
//0 1 2 3
//联通块的个数是:1
实验四 排序方法实践(2学时)
1、实验目的
通过本实验掌握排序的基本算法和过程以及查找的基本方法和过程。
2、实验内容
设计一个排序和查找系统。能够实现对给定的一组学生的借书证信息(如:卡号、姓名、系别、班号等)进行排序和查找。
1)按照卡号顺序进行排序;
2)能够实现查找某个系的所有的借书卡号并输出。
3、实验要求
(1)建立关于借书证信息结点的结构体;
收获:用C语言写了一下快排;#include<bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 10;
struct Node
{
int department;//系名
int number;//借书证卡号
char name[maxn];//姓名
char student_id[maxn];//学号
};
Node a[maxn];
void quicksort(Node a[],int left,int right)//按照系名进行排名
{
int i , j;
if(left >= right)
return ;
i = left , j = right;
a[0] = a[i];
while(i != j)
{
while(a[j].department > a[0].department && i < j)
-- j;
if(i < j)
{
a[i] = a[j];
i ++;
}
while(a[i].department < a[0].department && i < j)
++ i;
if(i < j)
{
a[j] = a[i];
j --;
}
}
a[i] = a[0];
quicksort(a,left,i - 1);
quicksort(a,i + 1,right);
}
void bin_search(Node a[],int n,int x)
{
int left = 1 ,right = n;
int ans = 0;
while(left <= right)
{
int mid = (left + right )/2;
if(a[mid].department == x)
{
ans = mid;
break;
}
else if(a[mid].department < x)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
if(!ans)
{
printf("没找到\n");
}
else
{
int start = ans,ends = ans;
while(a[start].department== x)
start --;
while(a[ends].department == x)
ends ++;
printf("%d系的信息为:\n",x);
for(int i = start + 1; i < ends ; i ++)
{
printf("%d %d %s %s\n",a[i].department,a[i].number,a[i].name,a[i].student_id);
}
}
}
int main()
{
int n;
printf("输入图书管理系统存有学生信息的个数:\n");
scanf("%d",&n);
printf("输入这%d个同学的各项信息\n",n);
for(int i = 1; i <= n ; i ++)
{
scanf("%d%d%s%s",&(a[i].department),&a[i].number,a[i].name,a[i].student_id);
}//输入一个大小为n的图书信息
quicksort(a,1,n);
printf("输出的是按系名排序后的信息是:\n");
for(int i = 1; i <= n ; i ++)
{
printf("%d %d %s %s\n",a[i].department,a[i].number,a[i].name,a[i].student_id);
}//
//按照系名进行二分索引并输出这个
int x;
printf("输入要输出的系名的信息:\n");
scanf("%d",&x);
//输入需要查找的系名
bin_search(a,n,x);
return 0;
}
//运行结果为:
//输入图书管理系统存有学生信息的个数:
//5
//输入这5个同学的各项信息
//1 12 123 1234
//1 21 321 4321
//4 12 345 5664
//3 45 676 8900
//3 56 789 7897
//输出的是按系名排序后的信息是:
//1 21 321 4321
//1 12 123 1234
//3 45 676 8900
//3 56 789 7897
//4 12 345 5664
//输入要输出的系名的信息:
//3
//3系的信息为:
//3 45 676 8900
//3 56 789 7897
//
//Process returned 0 (0x0) execution time : 5.468 s
//Press any key to continue.