zoukankan      html  css  js  c++  java
  • 算法导论第二章习题答案(第三版) Introduction to Algorithm

    Exercises
    2.1-1 略。
    2.1-2 略。
    2.1-3 
    C/C++ Code:
    int Search(int A[],int v){
    	for(int i=0;i++;i<=n)  //n表示数组中元素的个数
    		if(A[i]==v)
    			return i;
    	return NULL;
    }
    循环不变式:
    初始化:i=0,只有一个元素A[0],如果v=A[0],则返回0,否则返回NULL,算法显然是正确的。
    保持: 若算法对A[0...i]是正确的,当数组增加到A[0...i+1]时,只是多做了一次比较,显然也是正确的。
    终止: 如果经历了A.length次查找能找到必然会返回一个值,若没有成功,则会返回NULL。算法一定会返回一个返回值,要么成功返回等于v元素的下标,要么返回NULL,所以算法是正确的
    2.1-4 
    形式化描述: 数组A存放n位二进制整数的各位数值,数组B同样存放了另一个整数。通过二进制的加法进行运算,将结果保存在具有n+1个元素的数组C中。
    C/C++ Code:
    void Binary_Add(int a[],int b[],int c[]){
    	c[0]=0;
    	for(int i=0;i<=n;i++){          //n表示A,B数组中元素的个数
    		c[i+1]=(a[i]+b[i]+c[i])/2;
    		c[i]=a[i]^b[i]^c[i];
    	}
    }
    2.2-1 略。
    2.2-2 
    C/C++ Code:
    void Selection_Sort(int a[]){
    	int key,i,j,index;
    	for(j=0;j<=n-1;j++){
    		key=a[j];
    		index=j;
    		for(i=j+1;i<=n;i++)     //n表示数组中含有的元素个数
    			if(a[i]<key){
    				key=a[i];
    				index=i;
    			}
    		a[index]=a[j];
    		a[j]=key;
    	}
    }
    循环不变式:A[0...i-1]的数据都是排好序的。
    当你进行到n-1个元素的时候,后面就剩第n个元素了,注定是最大的,所以不用对其进行排序。
    无论是最好情况还是最坏情况,需要比较的次数都是一定的,所以时间复杂度都是Θ(n)。
    2.2-3
    平均需要检查n/2个元素。
    最坏需要检查n个元素。
    最坏情况和平均情况都应是Θ(n)。
    2.2-4
    控制算法的输入的数据,使其发生最好的情况。
    2.3-1 略。
    2.3-2 
    C/C++ Code:
    void Merge(int A[],int p,int k, int q){
    	int R[MAX],L[MAX];
    	int i,j,l;
    	for(i=0;i<=k-p;i++)
    		L[i]=A[p+i];
    	for(j=0;j<=q-k-1;j++)
    		R[j]=A[k+j+1];
    	i=j=0;
    	for(l=p;l<=q;l++){
    		if(i>k-p||j>q-k-1)  //其中任意一个数组中所有元素都被复制回A时,即终止循环
    			break;
    		if(L[i]>=R[j])
    			A[l]=R[j++];
    		else
    			A[l]=L[i++];
    	}
    	// 将另一个数组中的剩余元素复制回A
    	for(;i<=k-p;i++,l++)
    		A[l]=L[i];
    	for(;j<=q-k-1;j++,l++)
    		A[l]=R[j];
    }
    
    void Merge_Sort(int a[],int p,int q){
    	if(p<q){
    		int k=(p+q)/2;
    		Merge_Sort(a,p,k);
    		Merge_Sort(a,k+1,q);
    		Merge(a,p,k,q);
    	}
    }
    2.3-3
    1.当n=2时,即k=1时,可知.
    2.假设当k>2时,成立,则可以证明
    3.因此,当k>=1时,且n是2的幂时,
    2.3-4
    n=1或2时,T(n)=1;
    n>2时 ,
    2.3-5
    C/C++ Code:
    int Binary_Search(int a[],int m,int n,int v){
    	if(v>a[n]||v<a[m]||m==n)              //n代表数组中的元素数量
    		return NULL;
    	else{
    		int k;
    		k=(m+n)/2;
    		if(v==a[k])
    			return k;
    		else if(v>a[k])
    			Binary_Search(a,k+1,n,v);
    		else if(v<a[k])
    			Binary_Search(a,m,k,v);
    	}
    }
    该算法运行时间由比较的次数决定,最坏情况时,需要经过lgn次中点比较,最后要么找到返回该值,要么返回NULL,所以时间复杂度为Θ(lgn)。
    2.3-6
    不会的,虽然改用二分查找法的查找时间变为了lgn,但最后还是需要移动j-1个元素,所以算法时间复杂度无法改进到Θ(nlgn)。
    2.3-7
    1.构建一个辅助集合S‘,其中的元素为用x依次减去S中的元素。
    2.对S和S'分别进行排序。
    3.删除S中重复的元素,S’同样。
    4合并S和S‘,只要有相同的元素出现两次,其必然在相邻的位置,则可以确定S中存在两个其和刚好为x的元素。
    Thinking Problems
    2-1
    a.最坏情况下插入排序 排序一个长度为k的子表,所需时间为,所以编辑n/k个子表所需时间为Θ(nk)。
    b.在归并排序中,每一层的带价都是n,共有n/k个叶子节点,所以递归树的高度是lg(n/k),即lg(n/k)+1层,所以可以在Θ(nlg(n/k))内合并这些子表。
    c.若要使修改后的算法与归并排序有相同的运行时间,即Θ(nlg(n/k)+nk)=Θ(nlgn)。那么k必须小于lgn。
    d.k尽量大但要小于插入排序快于归并排序的临界值。
    2-2
    a.A'中排序好的元素就是A'中的元素,此时A‘中的元素即为A中的元素。
    b.循环不变式:A[j]是j到n中的最小值,
    初始化:j=n,A[n]必然是n到n中的最小值。
    保持:对于循环不变式可知,A[j...n]是已经排好序的,且A[j]是其最小值,那么只需要比较A[j]和A[j-1],就可以使A[j-1]是A[j-1...n]的最小值。
    终止:当j=i时终止此时A[i]也就是A[i...n]的最小值,此时A‘即为A中的元素。
    c.循环不变式:A[1...i-1]就是A[1...n]中的i-1个最小值,且已经排好序。
    初始化:i=1时,子数组为空,所以循环不变式成立。
    保持:若A[1...i-1]都是A[i...n]的排好序的i-1个最小值,那么A[i]即是剩下数组元素中的最小值,且A[1...i]是排好序的。
    终止:i=n时循环终止,此时A[1...n-1]都是A[1...n]中的n-1个最小值,因此A[1...n]是排好序的,且其中元素就是原A[1...n]中的元素。
    d.最坏运行时间:,与插入排序相同。
    2-3
    a.Θ(n)。
    b.C/C++ Code:
    int Multinomial(int a[],int n,int x){
    	int sum=a[0];
    	for(int i=1;i<=n;i++){
    		int xi=1;
    		for(int j=1;j<=i;j++)
    			xi=xi*x;
    		sum+=a[i]*xi;
    	}
    	return sum;
    }
    运行时间为,性能不如霍纳规则。
    c.循环不变式终止时有:i=-1,带入即可证得。
    d.循环不变式:
    初始化:i=n,y[n]=0,循环后有y[n]=a[n]。
    保持:对于 0<i<n,循环后有,
    终止:对于i=-1时终止,此时有
    所以上面给出的代码将正确的求出多项式的值。
    2-4
    a.略。
    b.{n,n-1,n-2....3,2,1}这样的数组有最多的逆序对,共有n(n-1)/2个逆序对。
    c.稍微修改一下归并排序即可,若当i<j时,L[i]>R[j],逆序对的数量count则加1,最后统计count的值即可,所以时间复杂度同归并排序,即为所求。
    (若有错误和不足,欢迎大家积极指正!)
    
    
  • 相关阅读:
    序列化-请求数据校验。。。。。。
    python自动化测试-D5-学习笔记之二(常用模块之加密模块)
    python自动化测试-D5-学习笔记之二(常用模块之os,sys,random,string,time)
    python自动化测试-D5-学习笔记之二(常用模块之json模块)
    python自动化测试-D5-学习笔记之一(argv的使用)
    python自动化测试-D5-学习笔记之一(函数补充,内置函数,map,filter,eval)
    python习题:写一个函数打印两个字典中不一样的key和value
    python习题:用文件方式编写购物车程序,添加,查看和删除
    python习题:时间格式转换
    python习题:双色球
  • 原文地址:https://www.cnblogs.com/hlj-ljz/p/3387019.html
Copyright © 2011-2022 走看看