2.1

2.1.1

执行过程如下:
《算法导论》第二章练习

2.1.2

按非升序排序的插入排序:

//插入排序,输入数组A和元素个数n
void insertion_sort(int A[],int n)
{
	for(int j=1;j<n;j++)
	{
		int key=A[j];
		int i=j-1;
		while(i>=0&&A[i]<key)
		{
			A[i+1]=A[i];
			i--;
		}
		A[i+1]=key;
	}
}
2.1.3

线性查找代码如下:

//线性查找
//输入数组A和元素个数n,以及查找元素v
//输出元素下标,或者不存在返回-1
int find_line(int A[],int n,int v)
{
	for(int i=0;i<n;i++)
	{
		if(A[i]==v)
			return i;
	}
	return -1;
}

证明:
初始化:初始时i=0,这个下标之前不存在元素,自然不存在v,满足条件。
保持:i次迭代时,A[0…i-1]不存在v,说明没有找到,保持循环不变式。
终止:有两种情况,一个是找到A[i]=v,返回i;一个是i>=n,没有找到,返回-1.
  其中的循环不变量是A[0…i-1],每次迭代都说明前i个元素没有找到v,想要下一次迭代,必须满足A[i]!=v。如果不满足,说明找到了,直接返回下标。不然如果超出循环,说明不存在,返回-1。算法正确。

2.1.4

二进制加法如下:

//二进制相加
//输入两个保存二进制的数组A,B和二进制位数n,以及保存结果的数组C
//输出相加的二进制,存在结果数组C里面
void add_two(int A[],int B[],int n,int C[])
{
	int k=0;//是否有进位
	for(int i=n-1;i>=0;i--)
	{
		C[i+1]=A[i]+B[i]+k;
		if(C[i+1]>1)
		{
			k=C[i+1]/2;
			C[i+1]%=2;
		}
		else
			k=0;
	}
	C[0]=k;//和的最高位
}

2.2

2.2.1

可以表示为 Θ(n3)\Theta(n^3)

2.2.2

选择排序如下:

//选择排序
//输入数组A和元素个数n
//输出排序结果
void select_sort(int A[],int n)
{
	int index,key;//保存中间结果
	for(int i=0;i<n-1;i++)
	{
		index=i;
		key=A[i];
		for(int j=i;j<n;j++)
		{
			if(A[j]<key)
			{
				key=A[j];
				index=j;
			}
		}
		int t=A[i];//交换
		A[i]=key;
		A[index]=t;
	}
}

循环不变式
初始化:i=0,此时数组未排序
保持:每次循环结束后保证A[0,i]的前i+1个元素排好序,是前i+1小的元素
终止:前n-1个元素排好序
  当前n-1各元素排好序以后,前n-1个最小元素在自己的位置,那么最后一个元素一定是最大元素,不需要再进行比较了。
  选择排序的最好和最坏时间都是Θ(n2)\Theta(n^2)

2.2.3

平均需要检查n+12\frac{n+1}{2}个元素,最坏情况需要检查n个元素,最坏和平均情况下时间都是Θ(n)\Theta(n)

2.2.4

需要根据具体的数据情况来设计最适合的算法,也就是根据数据倒推算法

https://www.jianshu.com/p/e1e09c220970

2.3

2.3.1

过程如下:《算法导论》第二章练习

2.3.2

代码如下:

//归并
//输入数组A和下标p,q,r
//输出合并后的数组
void merge(int A[],int p,int q,int r)
{
	int n1=q-p+1;
	int n2=r-q;
	int L[MAXSIZE],R[MAXSIZE];
	for(int i=0;i<n1;i++)
		L[i]=A[p+i];
	for(int i=0;i<n2;i++)
		R[i]=A[q+1+i];
	int s=0,t=0;//记录位置
	int k=0;//原数组的位置
	while(s<n1&&t<n2)
	{
		if(L[s]<=R[t])
		{
			A[p+k]=L[s];
			k++;s++;
		}
		else
		{
			A[p+k]=R[t];
			k++;t++;
		}
	}
	//处理剩余元素
	if(s==n1)//R数组剩余
	{
		while(t<n2)
		{
			A[p+k]=R[t];
			k++;t++;
		}
	}
	else if(t==n2)//L数组剩余
	{
		while(s<n1)
		{
			A[p+k]=L[s];
			k++;s++;
		}
	}
}

2.3.3

证明如下:

  1. 当n=2时,T(n)=2=nlg(n)T(n)=2=nlg(n),满足条件。
  2. 假设当为n是满足条件,即T(n)=nlg(n)T(n)=nlg(n);
  3. 当为2*n时,T(2n)=2T(n)+2n=2nlg(n)+2n=2n(lg(n)+1)=2nlg(2n)T(2n)=2T(n)+2n=2nlg(n)+2n=2n(lg(n)+1)=2nlg(2n)。满足题目要求。
  4. 综上所述,递归时的解是T(n)=nlg(n)T(n)=nlg(n)
2.3.4

递归实现如下:

//插入排序递归版本
//输入数组A和元素个数n,以及将要排的元素下标index
//输出排序后的数组
void insert_sort(int A[],int n,int index)
{
	if(index>=n)//全部排好序
		return;
	int key=A[index];
	for(int i=index-1;i>=0;i--)//从后往前遍历排好序的元素
	{
		if(A[i]>key)
		{
			A[i+1]=A[i];
		}
		else
		{
			A[i+1]=key;
			insert_sort(A,n,index+1);
			return;
		}
	}
	A[0]=key;
	insert_sort(A,n,index+1);
	return;
}

最坏运行时间是
T(n)={1n=1T(n1)+n)n&gt;1 T(n)=\left\{\begin{matrix} 1 &amp;n=1 \\ T(n-1)+n)&amp;n&gt;1 \end{matrix}\right.

2.3.5

二分查找代码如下:

//二分查找迭代版本
//输入排好序的数组A和元素个数n,查找元素v
//输出查找元素下标,或者不存在返回-1
int binary_sort(int A[],int n,int v)
{
	int l=0,r=n-1;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(A[mid]==v)
			return mid;
		else if(A[mid]>v)
			r=mid;
		else
			l=mid+1;
	}
	return -1;
}

最坏运行时间表达式如下:
T(n)={1n=1T(n/2)+1n&gt;1 T(n)=\left\{\begin{matrix} 1 &amp;n=1 \\ T(n/2)+1&amp;n&gt;1 \end{matrix}\right.
则解得最坏运行时间为Θ(lg(n))\Theta (lg(n))

2.3.6

改进后如下:

//插入排序二分版本
//输入数组A和元素个数n
//输出排序后的数组
void binary_insert_sort(int A[],int n)
{
	if(n<=1)//全部排好序
		return;
	for(int i=1;i<n;i++)
	{
		int key=A[i];
		int l=0,r=i-1;
		while(l<=r)
		{
			int mid=(l+r)/2;
			if(A[mid]>=key)
				r=mid-1;
			else
				l=mid+1;
		}
		for(int j=i-1;j>r;j--)
			A[j+1]=A[j];
		A[r+1]=key;
	}
}
2.3.7

这一题的解答参考了这位的博客https://blog.csdn.net/KongMing07/article/details/80146592

题目要求需要Θ(nlg(n))\Theta (nlg(n))的时间,很明显,如果是乱序的话很难达到要求,同时,排序的时间也要是Θ(nlg(n))\Theta (nlg(n))才行,这就需要快速排序、二分排序和归并排序,这里用上面改进的插入排序实现:

//寻找和为x的两个数
//输入数组A和元素个数n,要求的和x和
//输出和为x的两个数,返回是否找到
bool find_sum(int A[],int n,int x,int &a,int &b)
{
	binary_select_sort(A,n);
	int l=0,r=n-1;
	while(l<r)
	{
		if(A[l]+A[r]<x)
			l++;
		else if(A[l]+A[r]>x)
			r--;
		else
		{
			a=A[l];b=A[r];
			return true;
		}
	}
	return false;
}

相关文章: