算法导论第二章课后习题代码实现

插入排序代码实现:

#include<iostream>
using namespace std;
void Insert_sort(int a[],int length)
{
	int i,j,key;
	for(i=1;i<length;i++)
	{
		key=a[i];
		j=i-1;
		while(key<a[j])
		{
			int temp;
			temp=a[j+1];
			a[j+1]=a[j];
			a[j]=temp;
			j=j-1;
			if(j<0)
			{
				break;
			}
		}
	}
}
int main()
{
	int a[10]={2,3,3,4,8,67,89,24,35,72};
	Insert_sort(a,10);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}


 

习题答案

2.1-3,顺序查找数组中的某个数值

#include<iostream>
using namespace std;
int findvalue(int a[],int length,int v)
{
	int i,key=0;
	for(i=0;i<length;i++)
	{
		if(a[i]==v)
		{
			cout<<i<<endl;
			//return i+1;
			key++;
		}
	}
	return key;
}
int main()
{
	int a[10]={2,3,3,4,8,67,89,24,35,72};
	int v;
	while(cin>>v)
	{
		int value=findvalue(a,10,v);
		if(value==0)
		{
			cout<<"NIL"<<endl;
		}
	}
	return 0;
	
}


 

2.1-4二进制数想家问题,数组实现

#include<iostream>
using namespace std;
void convert(int a[],int n)
{
	int i;
	int temp;
	for(i=0;i<n/2;i++)
	{
		temp=a[i];
		a[i]=a[n-i-1];
		a[n-i-1]=temp;
	}
}
int *sum(int a[],int lengtha,int b[],int lengthb)
{
	convert(a,lengtha);
	convert(b,lengthb);
	int lengthc=lengtha>lengthb? lengtha:lengthb;
	lengthc+=1;
	int *c=new int [lengthc];
	memset(c,0,lengthc);
	int i,key=0;
	for(i=0;i<lengthc;i++)
	{
		if(lengtha<=i)
		{
			if(lengthb>i)
			{
				c[i]=b[i]+key;
				if(c[i]>=2)
				{
					c[i]%=2;
					key=1;
				}
				else
				{
					key=0;
				}
			}
			else 
			{
				c[i]=key;
			}
		}
		else if(lengtha>i)
		{
			if(lengthb>i)
			{
				c[i]=a[i]+b[i]+key;
				
			}
			else 
			{
				c[i]=a[i]+key;
				
			}
			if(c[i]>=2)
			{
				c[i]%=2;
				key=1;
			}
			else
			{
				key=0;
			}
		}
	}
	return c;
}
int main()
{
	int a[10]={1,0,1,0,1,1,0,0,1,1};
	int    b[9]={1,0,0,0,1,0,0,0,0};
	int *c;
	int i,key;
	c=sum(a,10,b,9);
	
	for(i=10;i>=0;i--)
	{
		if(c[i]!=0)
		{
			key=i;
			break;
		}
	}
	for(i=key;i>=0;i--)
	{
		cout<<c[i]<<" ";
	}
	return 0;
}


 

例题中的合并排序

#include<iostream>
using namespace std;
//a为数组,p和r为数组中要排序的范围的下标
void Merge_sort(int a[],int p ,int r)
{
	void Merge(int a[],int p ,int q,int r);
	if(p<r)
	{
		int q=(r+p)/2;
		Merge_sort(a,p,q);
		Merge_sort(a,q+1,r);
		Merge(a,p,q,r);
	}
}
void Merge(int a[],int p,int q,int r)
{
	int lena,lenb;
	lena=q-p+1;
	lenb=r-q;
	int Left[100],Right[100];
	int i,j=0,k=0;
	for(i=p;i<=q;i++)
	{
		Left[j++]=a[i];
	}
	Left[j]=10000000;
	j=0;
	for(i=q+1;i<=r;i++)
	{
		Right[j++]=a[i];
	}
	Right[j]=10000000;
	j=0;k=0;
	for(i=p;i<=r;i++)
	{
		if(Left[j]<Right[k])
		{
			a[i]=Left[j];
			j++;
		}
		else
		{
			a[i]=Right[k];
			k++;
		}
	}
}
int main()
{
	int a[10]={2,3,3,4,8,67,89,24,35,72};
	Merge_sort(a,0,9);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}


对合并排序的优化,去掉哨兵

//2.3-2 merge_sort修改版
//去掉哨兵
#include<iostream>
using namespace std;
//a为数组,p和r为数组中要排序的范围的下标
void Merge_sort(int a[],int p ,int r)
{
	void Merge(int a[],int p ,int q,int r);
	if(p<r)
	{
		int q=(r+p)/2;
		Merge_sort(a,p,q);
		Merge_sort(a,q+1,r);
		Merge(a,p,q,r);
	}
}
void Merge(int a[],int p,int q,int r)
{
	int lena,lenb;
	lena=q-p+1;
	lenb=r-q;
	int Left[100],Right[100];
	int i,j=0,k=0;
	for(i=p;i<=q;i++)
	{
		Left[j++]=a[i];
	}
	j=0;
	for(i=q+1;i<=r;i++)
	{
		Right[j++]=a[i];
	}
	j=0;k=0;
	int flag=0;
	for(i=p;i<=r;i++)
	{
		if(Left[j]<Right[k])
		{
			a[i]=Left[j];
			j++;
			if(j>=lena)
			{
				flag=1;
				break;
			}
		}
		else
		{
			a[i]=Right[k];
			k++;
			if(k>=lenb)
			{
				flag=2;
				break;
			}
		}
	}
	int count=0;
	i+=1;
	if(flag==1&&i<=r)
	{
		for(count=i;count<=r;count++)
		{
			a[count]=Right[k++];
		}
	}
	else if(flag==2&&i<=r)
	{
		for(count=i;count<=r;count++)
		{
			a[count]=Left[j++];
		}
	}
}
int main()
{
	int a[10]={2,3,3,4,8,67,89,24,35,72};
	Merge_sort(a,0,9);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}


 

习题2.3-4,插入排序递归版本实现

#include<iostream>
using namespace std;
void ReInsert(int a[],int p)
{
	void Insert(int b[],int n);
	int i;
	if(p>=0)
	{
		ReInsert(a,p-1);
	}
	Insert(a,p+1);
}
void Insert(int a[],int n)
{
	int i;
	int temp=a[n];
	if(n==0)
	{
		return ;
	}
	for(i=n-1;i>=0;i--)
	{
		if(a[n]>a[i])
		{
			for(int j=n;j>=i+2;j--)
			{
				a[j]=a[j-1];
			}
			a[i+1]=temp;
			break;
		}
	}
}
int main()
{
	int a[10]={2,3,3,4,8,67,89,24,35,72};
	ReInsert(a,9);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<' ';
	}
	cout<<endl;
}


 

2.3-6,修改的插入排序,使时间复杂度降为nlgn,修改的部分是while循环,将其改为二分查找

#include<iostream>
using namespace std;
void Insert_sort(int a[],int length)
{
	void BiInsert(int b[],int n);
	int i,j,key;
	for(i=1;i<length;i++)
	{
		key=a[i];
		j=i-1;
		BiInsert(a,j);
	}
}
void BiInsert(int a[],int n)
{
	int left,right,i,mid,temp;
	left=0;
	//关键,不要搞错
	right=n+1;
	temp=a[n+1];
	while(left<=right)
	{
		mid=(left+right)/2;
		if(left==mid)
		{
			if(temp<a[left])
			{
				for(i=n+1;i>left;i--)
				{
					a[i]=a[i-1];
				}
				a[left]=temp;
				return ;
			}
			else
			{
				for(i=n+1;i>left+1;i--)
				{
					a[i]=a[i-1];
				}
				a[left+1]=temp;
				return ;
			}
		}
		else if(right==mid)
		{
			if(temp>=a[mid])
				return ;
			else
			{
				for(i=n+1;i>right-1;i--)
				{
					a[i]=a[i-1];
				}
				a[right-1]=temp;
				return ;
			}
		}
		if(a[mid]==temp)
		{
			for(i=n+1;i>mid+1;i--)
			{
				a[i]=a[i-1];
			}
			a[mid+1]=temp;
			return ;
		}
		else if(a[mid]>temp)
		{
			if(temp>=a[mid-1])
			{
				for(i=n+1;i>mid;i--)
				{
					a[i]=a[i-1];
				}
				a[mid]=temp;
				return ;
			}
			else
			{
				right=mid;
			}
		}
		else
		{
			if(temp<a[mid+1])
			{
				for(i=n+1;i>mid+1;i--)
				{
					a[i]=a[i-1];
				}
				a[mid+1]=temp;
				return ;
			}
			else
			{
				left=mid;
			}
		}
	}
}
int main()
{
	int a[10]={2,7,3,5,8,67,89,24,35,72};
	Insert_sort(a,10);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	int b[10]={4,2,3,5,1,6,9,7,8,16};
	Insert_sort(b,10);

	for(i=0;i<10;i++)
	{
		cout<<b[i]<<" ";
	}
	cout<<endl;
	return 0;
}


2.3-6代码优化,修改后条例更加清晰

//2.3-6优化代码
//优化后的逻辑代码更加清晰条理,代码量减少
/*
#include<iostream>
using namespace std;
void Insert_sort(int a[],int length)
{
	void BiInsert(int b[],int n);
	int i,j,key;
	for(i=1;i<length;i++)
	{
		key=a[i];
		j=i-1;
		BiInsert(a,j);
	}
}
void BiInsert(int a[],int n)
{
	int left,right,i,mid,temp;
	left=0;
	//关键,不要搞错
	right=n+1;
	temp=a[n+1];
	if(temp>=a[n])
	{
		return;
	}
	else if(temp<=a[0])
	{
		for(i=n+1;i>0;i--)
		{
			a[i]=a[i-1];
		}
		a[0]=temp;
		return ;
	}
	while(left<=right)
	{
		mid=(left+right)/2;
		if(temp>=a[mid])
		{
			if(temp<=a[mid+1])
			{
				for(i=n+1;i>mid+1;i--)
				{
					a[i]=a[i-1];
				}
				a[mid+1]=temp;
				return ;
			}
			else
			{
				left=mid;
			}
		}
		else 
		{
			if(temp>=a[mid-1])
			{
				for(i=n+1;i>mid;i--)
				{
					a[i]=a[i-1];
				}
				a[mid]=temp;
				return ;
			}
			else 
			{
				right=mid;
			}
		}
		
	}
}
int main()
{
	int a[10]={72,7,89,8,5,67,3,24,35,2};
	Insert_sort(a,10);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	int b[10]={4,2,3,5,1,6,9,7,8,16};
	Insert_sort(b,10);

	for(i=0;i<10;i++)
	{
		cout<<b[i]<<" ";
	}
	cout<<endl;
	return 0;
}


习题2.3-7

求出给定集合中两个数之和为给定的整数

#include<iostream>
using namespace std;
void Merge_Sort(int a[],int p,int r)
{
	if(p<r)
	{
		int q;
		q=(r+p)/2;
		Merge_Sort(a,p,q);
		Merge_Sort(a,q+1,r);
		void Merge(int b[],int p,int q,int r);
		Merge(a,p,q,r);
	}
}
void Merge(int a[],int p, int q,int r)
{
	int Left[100],Right[100];
	int i,j,k,key;
	j=p;
	int lena=q-p+1;
	int lenb=r-q;
	for(i=0;i<lena;i++)
	{
		Left[i]=a[j];
		j++;
	}
	j=q+1;
	for(i=0;i<lenb;i++)
	{
		Right[i]=a[j];
		j++;
	}
	j=0;k=0;
	int flag=0;
	for(i=p;i<=r;i++)
	{
		if(j==lena)
		{
			flag=1;
			break;
		}
		else if(k==lenb)
		{
			flag=2;
			break;
		}
		if(Left[j]<=Right[k])
		{
			a[i]=Left[j];
			j++;
		}
		else
		{
			a[i]=Right[k];
			k++;
		}
	}
	if(flag==1)
	{
		for(key=i;key<=r;key++)
		{
			a[key]=Right[k];
			k++;
		}
	}
	else if(flag==2)
	{
		for(key=i;key<=r;key++)
		{
			a[key]=Left[j];
			j++;
		}
	}
}
int Bin_Serach(int a[],int length,int n,int num)
{
	int left,right;
	left=n;
	right=length;
	int mid;
	while(left<=right)
	{
		mid=(right+left)/2;
		if(mid==left&&a[left]>num)
		{
			return -1;
		}
		else if(mid == length-1&&a[length-1]<num)
		{
			return -1;
		}
		if(a[mid]==num)
		{
			return mid;
		}
		if(a[mid]<num)
		{
			if(num<a[mid+1])
			{
				return -1;
			}
			else
				left=mid;
		}
		else
		{
			if(num>a[mid-1])
			{
				return -1;
			}
			else
				right=mid;
		}
	}
	return -1;
}
int FindSum(int a[],int length,int n)
{
	int i,key;
	for(i=0;i<length;i++)
	{
		key=n-a[i];
		if(key<a[i])
		{
			cout<<"can't find those two elements!"<<endl;
			return -1;
		}
		else
		{
			int num=Bin_Serach(a,length,i+1,key);
			if(num!=-1)
			{
				return a[num];
			}
		}
	}
	return -1;
}
int main()
{
	int a[10]={72,7,89,8,5,67,3,24,35,2};
	Merge_Sort(a,0,9);
	int n;
	int key;
	for(int i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	while(cin>>n&&n>=0)
	{
		key=FindSum(a,10,n);
		if(key==-1)
		{
			continue;
		}
		else
		{
			cout<<"the two num is: "<<key<<" and : "<<n-key<<endl;
		}
	}
	return 0;
}


 

2.4,求数组中的逆序对的个数,实现思路是根据合并排序进行修改。算法时间复杂度为nlgn

#include<iostream>
using namespace std;
void Merge_Sort(int a[],int p,int r)
{
	if(p<r)
	{
		int q;
		q=(r+p)/2;
		Merge_Sort(a,p,q);
		Merge_Sort(a,q+1,r);
		void Merge(int b[],int p,int q,int r);
		Merge(a,p,q,r);
	}
}
void Merge(int a[],int p, int q,int r)
{
	int Left[100],Right[100];
	int i,j,k,key;
	int count=0;
	j=p;
	int lena=q-p+1;
	int lenb=r-q;
	for(i=0;i<lena;i++)
	{
		Left[i]=a[j];
		j++;
	}
	j=q+1;
	for(i=0;i<lenb;i++)
	{
		Right[i]=a[j];
		j++;
	}
	j=0;k=0;
	int flag=0,t=0;;
	for(i=p;i<=r;i++)
	{
		if(j==lena)
		{
			flag=1;
			break;
		}
		else if(k==lenb)
		{
			flag=2;
			break;
		}
		if(Left[j]<=Right[k])
		{
			a[i]=Left[j];
			j++;
		}
		else
		{
			a[i]=Right[k];
			int nn=count;
			count+=lena-j;
			int number;
			for(number=0;number<count-nn;number++)
			{
				t++;
				cout<<"the "<<t<<"th pair is :"<<Left[j+number]<<","<<Right[k]<<endl;
			}
			k++;
		}
	}
	if(flag==1)
	{
		for(key=i;key<=r;key++)
		{
			a[key]=Right[k];
			k++;
		}
	}
	else if(flag==2)
	{
		for(key=i;key<=r;key++)
		{
			a[key]=Left[j];
			j++;
		}
	}
}
int main()
{
	int a[10]={2,3,100,4,8,67,89,24,35,72};
	Merge_Sort(a,0,9);
	int i;
	for(i=0;i<10;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}


 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值