算法分析与设计习题集

  • 格式:doc
  • 大小:100.75 KB
  • 文档页数:7
动态规划
15、求出上图中每对结点间的距离的算法,并给出计算结果。
16、已知序列a1,a2,…,an,试设计一算法,从中找出一子序列
ai1< ai2<…< aik
使k达到最大,并讨论其复杂性。
17、设计一个O(n2)时间的算法,找出由n个数组成的序列的最长的单调递增子序列。
18、旅游预算问题。一个旅行社需要估算乘汽车从某城市到另一城市的最小费用,沿路有若干加油站,每个加油站收费不一定相同。旅游预算有如下规则:若油箱的油过半,不停车加油,除非油箱中的油不可支持到下一站;每次加油时都加满;在一个加油站加油时,司机要花费2元买东西吃;司机不必为其他意外情况而准备额外的油;汽车开出时在起点加满油箱;计算精确到分(1元=100分)。编写算法估计实际行驶在某路线所需的最小费用。
8、利用分治策略,在n个不同元素中找出第k个最小元素。
9、设有n个运动员要进行网球循环赛。设计一个满足以下要求的比赛日程表。
(1)每个选手必须与其它n-1选手各赛一次;
(2)每个选手一天只能赛一次。
10、已知序列{503,87,512,61,908,170,897,275,652,462},写一个自底向上的归并分类算法对该序列作升序排序,写出算法中每一次归并执行的结果。
19、下图表示城市之间的交通路网,线段上的数字表示费用,单向通行由A->E。试用动态规划的最优化原理求出A->E的最省费用。
20、已知如下图,写出用动态规划求最短路径的递推关系式,并写出求从源点A0到终点A3的最短路径过程。给出求解算法。
6
A1A2
55 2
A0A3
34 4
B1B2
5
21、已知有向图G=<V,E>,试设计一算法以判断对于任意两点u和v,是否存在一条从u到v的路径,并分析其复杂度。
if ( a->data[i]!= a->data[i+1])i++;
else
{
for ( j=i; j<a->length; j++)a->data[j]=a->data[j+1];
a->length--;
}
}
6、分别写出求二叉树结点总数及叶子总数的算法。
①计算结点总数
int CountNode(BinTree *root)
return(num1+num2+1);
}
}
②计算叶子总数
int CountLeafs(BinTree *root)
{
int num1,num2;
if(root==Null) return(0);
else if(root->lchild==Null&&root->rchild==Null)
return(1);
12、设有n个正整数,编写一个算法将他们连接成一排,组成一个最大的多位整数。用贪心法求解本题。
13、对于下图给出的有向网,写出用Dijkstra方法求从顶点A到图中其它顶点的最短路径的算法,并写出执行算法过程中顶点的求解次序及从顶点A到各顶点路径的长度。
14、对于上图给出的有向图,写出最小成本生成树,给出求解算法。
}
a++;
continue;
}
else
{ if (i==0)
return;
a[--i]++;
}
} while (1)
}
main()
{ comb(5,3);
}
24、(组合问题)任取r个自然数,求这r个数的所有排列。
25、编写程序求解骑士巡游问题:在n行n列的棋盘上(如n=8),假设一位骑士(按象棋中“马走日”的行走法)从初始坐标位置(x1,y1)出发,要遍访(巡游)棋盘中的每一个位置一次。请编一个程序,为骑士求解巡游“路线图”(或告诉骑士,从某位置出发时,无法遍访整个棋盘—问题无解骑士巡游)。
Procedure骑士巡游(X1,Y1)
//用x和y表示骑士在棋盘上的位置,采用回溯法求解,骑士巡游可以有以下8个可能方向的走法。
1 2 3 4 5 6 7 8
X+2,Y+2
//
integer k, n, m, X,Y;
integer X(64), S(0:64, 1: 2);
S(0)(0,X1,Y1);
if(j<=t) rf[k…t]=r[j…t];
}
void MergeSort(S_TBL *p,ElemType *rf)
{/*对*p表归并排序,*rf为与*p表等长的辅助数组*/
ElemType *q1,*q2;
q1=rf;q2=p->elem;
for(len=1;len<p->length;len=2*len)/*从q2归并到q1*/
采用回溯法找问题的解,将找到的组合以从小到大顺序存于a[0],a[1],…,a[r-1]中,组合的元素满足以下性质:
(1)a[i+1]>a,后一个数字比前一个大;
(2)a-i<=n-r+1。
按回溯法的思想,找解过程可以叙述如下:
首先放弃组合数个数为r的条件,候选组合从只有一个数字1开始。因该候选解满足除问题规模之外的全部条件,扩大其规模,并使其满足上述条件(1),候选组合改为1,2。继续这一过程,得到候选组合1,2,3。该候选解满足包括问题规模在内的全部条件,因而是一个解。在该解的基础上,选下一个候选解,因a[2]上的3调整为4,以及以后调整为5都满足问题的全部要求,得到解1,2,4和1,2,5。由于对5不能再作调整,就要从a[2]回溯到a[1],这时,a[1]=2,可以调整为3,并向前试探,得到解1,3,4。重复上述向前试探和向后回溯,直至要从a[0]再回溯时,说明已经找完问题的全部解。按上述思想写成程序如下:
X(1)0; k1; m8
while k>0 do
X(k)X(k)+1
while X(k)≤m and not MOVE(k) do
X(k)X(k)+1
repeat
if X(k)≤m then
if k=64 then
print(X,S);return;
else
kk+1; //此处未判是否越界,即栈溢出。//
本题的算法思想是:由于顺序表中元素已按元素值非递减有序排列,值相同的元素比为相邻的元素,因此依次比较相邻两个元素,若值相等,则删除其中一个,否则继续向后查找,直到最后一个元素。实现本题功能的函数如下:
voiddel ( seqlist*a )
{
inti=0, j;
while ( i<a->length)
算法分析与设计习题集
基础篇
1、算法有哪些特点?它有哪些特征?它和程序的主要区别是什么?
2、算法的时间复杂度指的是什么?如何表示?
3、算法的空间复杂度指的是什么?如何表示?
4、设某一函数定义如下:
编写一个递归函数计算给定x的M(x)的值。
本函数是一个递归函数,其递归出口是:
M(x)= x-10x>100
:X(k)=3: S(k)( S(k-1,1)+1, S(k-1,2)+2 );
:X(k)=4: S(k)( S(k-1,1)+2, S(k-1,2)+1 );
:X(k)=5: S(k)( S(k-1,1)+2, S(k-1,2)-1 );
:X(k)=6: S(k)( S(k-1,1)+1, S(k-1,2)-2 );
endif
for ik - 1 to 0 by -1 do
if S(i)=S(k) then
return(FALSE);
endif
repeat
return(TRUE);
ENDMOVE
【程序】
# define MAXN 100
int a[MAXN];
void comb(int m,int r)
{ int i,j;
i=0;
a=1;
do {
if (a-i<=m-r+1
{ if (i==r-1)
{ for (j=0;j<r;j++)
printf(“%4d”,a[j]);
printf(“\n”);
22、判近亲问题。给定一个家族族谱,为简化问题起见,假设家族中的夫妻关系只表示男性成员。设用线性表存储家族成员,用成员的父指针指向其生父。编写一个在此种族谱表示方式下的算法,判断给定的二个家族成员是否是五代内的近亲。(提示:家族成员的表示方式应与搜索方式相适应。)
23、(组合问题)求出从自然数1,2,…,n中任取r个数的所有组合。
elseif(i<=p->length)
while(i<=p->length)/*若还剩下一个子表,则直接传入*/
q1[i]=q2[i];
q1<-->q2;/*交换,以保证下一趟归并时,仍从q2归并到q1*/
if(q1!=p->elem)/*若最终结果不在*p表中,则传入之*/
for(i=1;i<=p->length;i++)
else
{
num1=CountLeafs(root->lchild);
num2=CountLeafs(root->rchild);
return(num1+num2);
}
}
分治术
7、有金币15枚,已知其中有一枚是假的,而且它的重量比真币轻。要求用一个天平将假的金币找出来,试设计一种算法(方案),使在最坏情况下用天平的次数最少。