k=j;
if(k!
=i){temp=a[i];a[i]=a[k];a[k]=temp;}
}
}
/*快速排序*/
intpart(inta[n],intlow,inthigh)
{intx;
x=a[low];
while(low{
while(low=x)
--high;
a[low]=a[high];
while(low++low;
a[high]=a[low];
}
a[low]=x;
returnlow;
}
voidQsort(inta[n],intlow,inthigh)
{intpivotloc;
if(low{pivotloc=part(a,low,high);
Qsort(a,low,pivotloc-1);
Qsort(a,pivotloc+1,high);
}
}
main()
{
inta[n],j;
for(j=0;jscanf("%d",&a[j]);
maopao(a);for(j=0;jprintf("%5d",a[j]);
printf("\n");
for(j=0;jscanf("%d",&a[j]);
xuanze(a);for(j=0;jprintf("%5d",a[j]);printf("\n");
for(j=0;jscanf("%d",&a[j]);
Qsort(a,0,n-1);for(j=0;jprintf("%5d",a[j]);printf("\n");
getch();
}
2、用C语言实现下列各种操作
1)单链表的建立
2)在第i个结点之前插入一个结点
3)删除第i个结点
#defineNULL0
typedefstructnode{
intdata;
structnode*next;
}node,*link;
/*单链表建立
voidcrealink(link*L,intn)
{linkp,q;
inti;
*L=(link)malloc(sizeof(node));
q=*L;
q->next=NULL;
for(i=1;i<=n;++i)
{p=(link)malloc(sizeof(node));
printf("inputp->data=");
scanf("%d",&p->data);
p->next=NULL;
q->next=p;
q=p;
}
}
/*单链表的输出*/
voidprint(linkL)
{linkp;
p=L->next;
while(p)
{printf("%5d",p->data);
p=p->next;
}
printf("\n");
}
/*在单链表的第I个位置上插入元素值为e的函数*/
voidinsert(link*L,inti,inte)
{linkp,s;intj=0;
p=*L;
/*找被插入位置,p指向i-1位置*/
while(p&&j{p=p->next;++j;}
if(!
p||j>i)
printf("error");
else{
/*申请结点*/
s=(link)malloc(sizeof(node));
s->data=e;
/*插入*/
s->next=p->next;
p->next=s;
}
}
/*删除单链表的第I个位置上的元素值*/
voiddelink(link*L,inti)
{linkp,s;intj=0;
p=*L;
/*查找被删位置,p指向i-1位置*/
while(p&&j{p=p->next;++j;}
if(!
p||j>i)
printf("error");
else{
s=p->next;/S指向被删结点*/
p->next=s->next;
free(s);
}
}
main()
{linkL;
intn,i,e;/*链表结点的个数*/
printf("inputlinkn=");
scanf("%d",&n);
crealink(&L,n);
print(L);
/*i表示被插位置*/
printf("inputi=");
scanf("%d",&i);
/*i表示被插值*/
printf("inpute=");
scanf("%d",&e);
insert(&L,i,e);
print(L);
/*i表示被删位置*/
printf("inputi");
scanf("%d",&i);
delink(&L,i);
print(L);
getch();
}
3、用C语言实现下列各种操作
1)二叉树的建立用递归法
2)用递归方法对二叉树进行全序、中序、后序遍历及用非递归方法对树进行层次遍历
#defineNULL0
/*定义二叉树中的结点*/
typedefstructnode
{chardata;
structnode*lch,*rch;
}node,*link;
/*用先序遍历的思想建立二叉树*/
voidcreat(link*t)
{charch;
scanf("%c",&ch);
if(ch=='0')*t=null;
else
{
*t=(link)malloc(sizeof(node));
(*t)->data=ch;
creat(&(*t)->lch);
creat(&(*t)->rch);
}
}
/*先序遍历函数*/
voidpreorder(linkt)
{
if(t!
=null)
{printf("%c",t->data);/*访问根结点*/
inorder(t->lch);/*先序遍历左子树*/
inorder(t->rch);/*先序遍历右子树*/
}
}
/*中序遍历函数*/
voidinorder(linkt)
{
if(t!
=null)
{
inorder(t->lch);/*中序遍历左子树*/
printf("%c",t->data);/*访问根结点*/
inorder(t->rch);/*中序遍历右子树*/
}
}
/*后序遍历函数*/
voidpostorder(linkt)
{
if(t!
=null)
{
postorder(t->lch);/*后序遍历左子树*/
postorder(t->rch);/*访问根结点*/
printf("%c",t->data);/*后序遍历右子树*/
}
}
/*二叉树的层次遍历*/
voidlever(linkt)
{linkp;
/*定义空队列*/
bitreeQ[100];
intfront=0,rear=0;
/*初始化队列为空队列*/
Q[rear++]=t;
/*当队列为非空时*/
while(front!
=rear)
{p=Q[front++];/*对头元素出队列*/
printf("%5d",p->data);
/*对头元素左孩子不空,将左孩子入队列*/
if(p->lch!
=NULL)
Q[rear++]=p->lch;
/*对头元素左孩子不空,将左孩子入队列*/
if(p->rch!
=NULL)
Q[rear++]=p->rch;
}
}
main()
{
linkt;
creat(&t);
prorder(t);
printf("\n");
inorder(t);
printf("\n");
postorder(t);
printf("\n");
lever(t);
printf("\n");
getch();
}
4、用C语言实现下列各种操作
1)用邻接表法建立有向图的邻接表
2)用深度优先和广度优先法来遍历该有向图
#defineNULL0
/*定义访问数组*/
intvisited[100];
/*邻接点及顶点的定义*/
typedefstructnode
{intadjvex;
structnode*next;}node;
/*顶点的定义*/
typedefstruct
{intvex;
node*firstadj;
}vertex;
/*邻接表的定义*/
typedefstruct
{vertexdata[100];
intm;/*m表示图中顶点的个数*/
}adjlist;
/*voidcreategraph(adjlist*g)
功能:
建立有向图的邻接表,图中的边由键盘给出。
voiddfs(adjlistg)
功能:
完成有向连通图的深度优先遍历。
voidbfs(adjlistg)
功能:
完成有向连通图的广度优先遍历。
有向图的邻接表的建立程序*/
voidcreategraph(adjlist*g)
{intn,e;/*n表示图中的顶点个数,e表示边的条数*/
intj,i,k;
node*p,*q;
/*由键盘输入图的顶点个数及边的条数*/
printf("inputn=");
scanf("%d",&n);
printf("inpute=");
scanf("%d",&e);
/*初始化邻接表*/
g->m=n;
for(j=0;j<=n-1;++j)
{g->data[j].firstadj=NULL;
g->data[j].vex=j;
}
for(j=0;j{/*由键盘输入一对边*/
printf("inputi,k:
");
scanf("%d%d",&i,&k);
/*申请一个邻结点*/
p=(node*)malloc(sizeof(node));
p->adjvex=k;
p->next=NULL;
if(g->data[i].firstadj==NULL)
g->data[i].firstadj=p;
else
{q=g->data[i].firstadj;
while(q->next)
q=q->next;
q->next=p;
}
}
}
/*有向图的深度优先遍历*/
voiddfs(adjlistg,intv)
{node*p;
printf("%3d",v);
visited[v]=1;
p=g.data[v].firstadj;
while(p)
{if(visited[p->adjvex]==0)dfs(g,p->adjvex);
p=p->next;
}
}
/*有向图的广度优先遍历程序*/
voidbfs(adjlistg,intv)
{/*定义空队列*/
intQ[100];
intfront=0,rear=0;
node*p;
visited[v]=1;
printf("%3d",v);
Q[rear++]=v;
while(front!
=rear)
{v=Q[front++];
p=g.data[v].firstadj;
while(p)
{if(visited[p->adjvex]==0)
{visited[p->adjvex]=1;
printf("%3d",p->adjvex);
Q[rear++]=p->adjvex;
}
p=p->next;
}
}
}
/*主函数如下:
*/
main()
{adjlistg;
inti;
creategraph(&g);
/*初始化访问数组*/
for(i=0;idfs(g,0);
printf("\n");
/*初始化访问数组*/
for(i=0;ibfs(g,0);
getch();
}
5、迷宫程序
#definem6
#definen9
voidpath()
{/*定义迷宫并初始化迷宫*/
intmaze[8][11]={1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,0,0,1,1,0,0,1,
1,1,0,0,0,1,1,0,1,1,1,
1,0,1,1,0,0,0,0,1,1,1,
1,1,1,0,1,1,1,1,0,1,1,
1,1,1,0,1,0,0,1,0,0,1,
1,0,0,1,1,1,0,1,1,0,1,
1,1,1,1,1,1,1,1,1,1,1}
;
intmove[9][2];
/*定义栈*/
ints[54][3];
inttop=0;
inti,j,k,p,f=0,g,h;
/*初始化增量矩阵*/
move[1][0]=-1;move[1][1]=0;
move[2][0]=-1;move[2][1]=1;
move[3][0]=0;move[3][1]=1;
move[4][0]=1;move[4][1]=1;
move[5][0]=1;move[5][1]=0;
move[6][0]=1;move[6][1]=-1;
move[7][0]=0;move[7][1]=-1;
move[8][0]=-1;move[8][1]=-1;
maze[1][1]=2;
/*初始化栈非空*/
s[top][0]=1;
s[top][1]=1;
s[top][2]=3;
++top;
while(top!
=0&&f==0)
{/*退栈*/
--top;
i=s[top][0];
j=s[top][1];
k=s[top][2];
/*当方向数小于8时*/
while(k<=8)
{/*试老鼠的下一位置*/
g=i+move[k][0];
h=j+move[k][1];
if(g==m&&h==n&&maze[g][h]==0)
{for(p=0;p{
printf("%d,%d,%d\n",s[p][0],s[p][1],s[p][2]);}
printf("%d,%d,%d\n",i,j,k);
printf("%d,%d,%d\n",m,n,k);
f=1;
}
if(maze[g][h]==0)
{maze[g][h]=2;
/*下一位置可通,将上一位置入栈*/
s[top][0]=i;
s[top][1]=j;
s[top][2]=k;
++top;
/*改变老鼠的当前位置*/
i=g;
j=h;
k=0;
}
/*方向数增1*/
k=k+1;
}
}
if(f==0)
printf("nopath\n");
}
main()
{
path();
getch();
}
6、约瑟夫问题程序
#defineNULL0
typedefstructQNode
{intdata;
structQNode*next;
}QNode,*linklist;
/*建立循环链表*/
voidcreate(linklist*L,intn)
{inti;
linklistp,q;
*L=(QNode*)malloc(sizeof(QNode));
(*L)->next=NULL;
q=*L;
for(i=1;i<=n;++i)
{p=(QNode*)malloc(sizeof(QNode));
p->data=i;
q->next=p;q=p;
}
q->next=(*L)->next;*L=(*L)->next;
}
/*输出循环链表*/
voidprint(linklistL)
{linklistp;
p=L;
while(p->next!
=L)
{printf("%5d",p->data);
p=p->next;
}
printf("%5d",p->data);
printf("\n");
}
/*报数到第m号出圈*/
voidjone(linklistL,intm)
{linklistp,q;inti,j;
p=L;
/*将指针定位到k-1号位*/
for(i=1;ip=p->next;
/*从第k号位置开始报数,k报1号,k+1报2号,依次类推,将指针指向最后一个报数的人*/
while(p->next!
=p)
{j=1;
while(p->next!
=p&&j{p=p->next;++j;}
q=p->next;
printf("%5d",q->data);
/*删除第m号*/
p->next=q->next;
p=p->next;
free(q);
}
printf("\nzuihouyigeshi:
%5d",p->data);
}
main()
{linklistL;
create(&L,100);
print(L);
jone(L,10);
getch();
}
7、Kruskal算法的设计
[实验目的]
1.根据算法设计需要,掌握连通网的灵活表示方法;
2.掌握最小生成树的Kruskal算法;
3.基本掌握贪心算法的一般设计方法;
4.进一步掌握集合的表示与操作算法的应用.
[预习要求]
1.认真阅读算法设计教材和数据结构教材内容,熟习连通网的不同表示方法和最小生成树算法;
2.设计Kruskal算法实验程序.
[参考数据类型或变量]
typedefNodeNumberint;/*节点编号*/
typedefCostTypeint;/*成本值类型*/
typedefElemTypeNodeNumber/*实型或任意其它元素类型*/
typedefstruct{intElemType;inttag;}NODE;
typedefstruct{CostTypecost;NodeNumbernode1,node2;}EDGE;
NODEset[]={{1,-1},…,{n,-1}};/*节点集,n为连通网的节点数*/
EDGEes[]={{valuesofe1},…,{valuesofem}};/*边集,m为连通网的边数*/
EDGEst[n-1];/*最小生成树的边集*/
[参考子程序接口与功能描述]
intFind(NODE*set,ElemTypeelem)
功能:
在数组set中顺序查找元素elem,如果不成功,返回-1;否则,使用带压缩规则的查找算法,返回所在子集的根节点索引.
intUnion(NODE*set,ElemTypeelem1,ElemTypeelem2)
功能:
应用Find算法首先找到elem1和elem2所在的子集,然后应用带加权规则的并运算算法合并两个子集.不成功时,返回-1;否则,返回并集的根节点索引.
voidSort(EDGE*es,intn)
功能:
用任意分类算法将连通图的边集按成本值的非降次序分类.
voidKruskal(EDGE*es,intm,NODE*set,intn,EDGE*st)
功能:
对有n个节点,m条边的连通网,应用Kruskal算法生成最小生成树,最小生成树的边存储在数组st中.
voidOutput(EDGE*st,intn)
功能:
输出最小生成树的各条边.
[实验步骤]
1.设计测试问题,修改并调试程序,输出最小生成树的各条边,直至正确为止;
2.待各功能子程序调试完毕,去掉测试程序,将你的程序整理成功能模块存盘备用.
[实验报告要求]
1.阐述实验目的和实验内容;
2.阐述Kruskal算法的原理方法;
3.提交实验程序的功能模块;
4.提供测试数据和相应的最小生成树.
[思考与练习]
1.设计由连通网初始边集数组生成最小堆的算法;
2.设计输出堆顶元素,并将剩余元素调整成最小堆的算法;
3.针对连通网初始边集最小堆表示,设计Kruskal算法;
4.采用成本邻接矩阵表示连通网时,在剩余边中如何实现最小成本边的查找?
5.采用成本邻接矩阵表示连通网时,用C语言实现Prim算法.
8、实验六回溯算法设计
[实验目的]
1.掌握回溯法解题的基本思想;
2.掌握回溯算法的设计方法;
3.针对子集和数问题,熟练掌握回溯递归算法、迭代算法的设计与实现。
[预习要求]
1.认真阅读教材或参考书,掌握回溯法解题的基本思想,算法的抽象控制策略;
2.了解子集和数问题及解向量的定长和变长状态空间表示;
3.针对解向量的定长表示,设计状态空间树节点扩展的规范(限界)函数及实现方法;
4.分析深度优先扩展状态空间树节点或回溯的条件;
5.分析和设计生成解向量各分量可选值的实现方法;
6.设计和编制回溯算法的递归和迭代程序。
[参考数据类型或变量]
floats;//表示有可能抵达答案节点的子路径上的元素之和;
floatr;//尚未测试的剩余集合元素之和;
floatw[n];//存储原始集合的n个元素,根据问题实例初始化;
intx[n];//定长表示的解向量,各元素初始值为0;
[参考子程序接口与功能描述]
voidRecursiveSubset(floats,floatr,intk)
功能:
针对问题