算法导论第二章部分习题自我解答

练习:

2.3-2:去掉合并排序中的哨兵值

#include <iostream>
using namespace std;
void Merge(int* A, int p, int q, int r){
	int n1 = q-p+1;
	int n2 = r-q;
	int *L = new int[n1+1];
	int *R = new int[n2+1];
	for(int i=0; i<=n1-1; i++)
		L[i] = A[p+i-1];
	for(int j=0; j<=n2-1; j++)
		R[j] = A[q+j];
	int i = 0;
	int j = 0;
	int k;
	for(k=p-1; k<=r-1 && i!=n1 && j!=n2; k++){//去掉哨兵后则要增加终止判断
		if(L[i]<=R[j]){
			A[k] = L[i];
			i++;
		}else{
			A[k] = R[j];
			j++;
		}
	}
	//*********去掉哨兵后,加入这部分即可*********//
	if(i == n1 || j == n2){
		while(k<=r-1){
			if(i == n1)
				A[k] = R[j++];
			else
				A[k] = L[i++];
			k++;
		}
	} 
	delete[] L;
	delete[] R;
	//*****************************************//
}
void MergeSort(int* A, int p,int r){
	if(p<r){
		int q = (p+r)/2;
		MergeSort(A, p, q);
		MergeSort(A, q+1, r);
		Merge(A, p, q, r);
	}
}
int main(){
	int A[]={10,9,4,7,8,3,1,15,12};
	int length_A = 9;;
	MergeSort(A, 1, length_A);
	for(int i=0; i<length_A; i++)
		cout<<A[i]<<" ";
	return 0;
}
2.3-4:插入排序的递归版

#include <iostream>
using namespace std;
void InsertionSort(int *A, int length_A){
	int last = length_A-1;
	if(last > 0){
		InsertionSort(A, length_A-1);
		int key = A[last];
		int i;
		for(i=last-1; i>=0 && A[i]>key; i--)
			A[i+1] = A[i];
		A[i+1] = key;		
	}
}
int main(){
	int A[]={10,9,4,7,8,3,1};
	int length_A = 7;
	InsertionSort(A, length_A);
	for(int i=0; i<length_A; i++)
		cout<<A[i]<<" ";
	return 0;
}

思考题:

2-2.证明冒泡排序的正确性:

b) 2-4行的循环不变式为:A[j] = min{A[i] | i = j to n}

证明:初始时,j=length[A],此时A[j]为末尾元素,它后面没有值了,满足。

    假设k次迭迭代前,j = k,满足循环不变式,则下次(k-1)迭代前,j  = k -1,在之前执行了把A[k]和A[k-1]中的小数放到前面的操作,故这时A[k-1]仍比后面的元素都小,满足;

    终止条件是,当j = i时,这时A[i]就是A[i]到A[n]中最小的值。

c) 利用b)的终止条件,1-4行的循环不变式为:A[1]<=A[2]<=..<=A[i]

证明:初始时,A[i] = A[1],单个元素有序;

    假设k次迭代前,i = k,满足A[1]到A[k]有序,第k+1次迭代前,利用b)的终止条件A[k]<=A[k+1],得,满足;

    终止条件是,当i = length[A]时,全部有序。

d) 最坏运行时间:求和[((n^2)-n)/2];比插入算法效率高一些,但增长率相同。

附上冒泡排序程序:

#include <iostream>
using namespace std;
void BubbleSort(int *A, int length_A){
	int last = length_A-1;
	for(int i=0; i<=last; i++){
		for(int j=last; j>=i+1; j--){
			if(A[j-1]>A[j]){
				int temp = A[j];
				A[j] = A[j-1];
				A[j-1] = temp;
			}
		}
	}
}
int main(){
	int A[]={10,9,4,7,8,3,1};
	int length_A = 7;
	BubbleSort(A, length_A);
	for(int i=0; i<length_A; i++)
		cout<<A[i]<<" ";
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值