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

来源:互联网 发布:微信报码编码软件 编辑:程序博客网 时间:2024/05/16 14:32

插入排序代码实现:

#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;}elseleft=mid;}else{if(num>a[mid-1]){return -1;}elseright=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;}


 

 

原创粉丝点击