"设计算法统计给定排列中含 有逆序的个数。 //用归并进行排序 //当一个子集的一个数大于第二个子集的一个数,为逆序,即 a[i]>a[j] //则逆序数为 end-j+1; #include using namespace std; int count; void Merge(int a[],int a1[],int begin,int mid,int end)//合并子序列 { int i=begin,j=mid+1,k=end; while(i<=mid&&j<=end) { if(a[i]<=a[j]) a1[k++]=a[i++];//取 a[i]和 a[j]中较小者放入 r1[k] else { a1[k++]=a[j++]; count+=(end-j+1); } } while(i<=mid) a1[k++]=a[i++]; while(j<=end) a1[k++]=a[j++]; } void MergeSort(int a[ ], int begin, int end) { int mid,a1[1000]; if(begin==end) return ; else { mid=(begin+end)/2; MergeSort(a,begin,mid); MergeSort(a,mid+1,end); Merge(a,a1,begin,mid,end); } } int main() { int a[6]={6,5,4,3,2,1}; count=0; MergeSort(a,0,6); cout< using namespace std; int n; char a[100]; void gelei(int k) { if(k==n) { cout<>n && n != 0) { memset(a,'0',sizeof(a)); //初始化,全部置零 a[n] ='\0'; gelei(0); cout< r[mid]) low = mid; else return mid; } return 0; } 错误。 正确算法: int BinSearch1(int r[ ], int n, int k) { int low = 0, high = n - 1; int mid; while (low <= high) { mid = (low + high) / 2; if (k < r[mid]) high = mid - 1; else if (k > r[mid]) low = mid + 1; else return mid; } return 0; } 2. 请写出折半查找的递归算法,并分析时间性能。 //折半查找的递归实现 #include using namespace std; int digui_search(int a[],int low,int high,int x) { if (low > high) return 0; int mid = (low+high)/2; if (a[mid] == x) return mid; else if (a[mid] < x) digui_search(a,low,mid-1,x); else digui_search(a,mid+1,high,x); } int main() { int a[6]={0,1,2,9,5,3}; int result=digui_search(a,0,5,5); cout< using namespace std; //折半进行范围查找函数: void digui_search(int min, int max, int a[], int low, int high) { int mid; mid=(low+high)/2; if(a[mid]max) digui_search(min, max, a, low, mid); else { for(int i=mid; a[i]>=min && i>=low; i--) cout<>r[i]; cout<<""请输入查找范围最小值 min 和最大值 max:""<<"" ""; cin>>min>>max; digui_search(min, max, r, 0, 5); cout< using namespace std; int main (void) { int a,b; int i=1; cin>>a>>b; while((i%a!=0)||(i%b!=0)) ++i; cout<<""a,b 最小公倍数为:""< r[j]) break; else { temp = r[i]; r[i] = r[j]; r[j] = temp; i = j; j = 2 * i + 1; } } } 进行调堆! //比较 i 的左右孩子,j 为较大者 //根结点已经大于左右孩子中的较大者 //将被筛结点与结点 j 交换 //被筛结点位于原来结点 j 的位置 6. 设计算法实现在大根堆中删除一个元素,要求算法的时间复杂性为 O(log2n)。 //将要删除的 a[k]与最后一个元素 a[n-1]交换 //然后进行调堆 void de_SiftHeap(int r[ ], int k, int n) { int i, j, temp,temp1; i = k; j = 2 * i + 1; if(i<0||i>n-1) return error; else if(i==n-1) free(a[i]); else while (j < n) //置 i 为要筛的结点,j 为 i 的左孩子 //筛选还没有进行到叶子 { temp1=a[i]; //将 a[n-1]与 a[k]交换; a[i]=a[n-1]; a[n-1]= temp1; if (j < n-1 && r[j] < r[j+1]) j++; //比较 i 的左右孩子,j 为较大者 if (r[i] > r[j]) //根结点已经大于左右孩子中的较大者 break; else { temp = r[i]; r[i] = r[j]; r[j] = temp; i = j; j = 2 * i + 1; //将被筛结点与结点 j 交换 //被筛结点位于原来结点 j 的位置 } } } 7. 计算两个正整数 n 和 m 的乘积有一个很有名的算法 称为俄式乘法,其思想是利用了一个规模是 n 的解和一个 规模是 n/2 的解之间的关系:n×m=n/2×2m(当 n 是偶 数)或:n×m=(n-1)/2×2m+m(当 n 是奇数),并以 1 nm 50 65 25 130 130 12 260 6 520 3 1040 1040 1 2080 + 2080 3250 图 5.15 俄式乘法 ×m=m 作为算法结束的条件。例如,图 5.15 给出了利用俄式乘法计算 50×65 的例子。据 说十九世纪的俄国农夫使用该算法并因此得名,这个算法也使得乘法的硬件实现速度非常 快,因为只使用移位就可以完成二进制数的折半和加倍。请设计算法实现俄式乘法。 //俄式乘法 #include using namespace std; int fun(int m,int n) { int sum=0; int temp=n; while(m!=1) { if(m%2==0)//如果 n 是偶数 { n=n*2; m=m/2; } else//如果 n 是奇数 { n=n*2; sum+=temp; m=(m-1)/2; } temp=n;//记录倒数第二个 n 的值 } return sum+n; } int main() { int a,b; while(cin>>a>>b) { cout< using namespace std; long ackman(long m, long n) { long stack[10000]; int pos=1; stack[0]=m;stack[1]=n; while(pos) { n=stack[pos--]; m=stack[pos]; if(m==0) stack[pos]=n+1; if(m!=0&&n==0) { stack[pos++]=m-1; stack[pos]=1; } if(m!=0&&n!=0) { stack[pos++]=m-1; stack[pos++]=m; stack[pos]=n-1; } } return stack[0]; } int main(int argc, char *argv[]) { long m,n; cin>>m>>n; cout< #define N 100000 #define M 20 int a[N][M]; int value[M]; using namespace std; int main() { while(true) { int i,j,k; int x,y,z; cout<<""输入货币种类的个数:""<>x; cout<<""从小到大输入货币的价值,其中第一个必须为一:""<>y; value[i]=y; } cout<<""输入要兑换的钱的价值:""<>z;//z 为钱 for(j=0;j<=z;j++) a[j][0]=0; for(k=0;k<=x;k++) a[0][k]=0; for(i=1;i<=z;i++) { for(j=1;j<=x;j++) { if(value[j]==i) a[i][j]=1; else if(value[j]>i) a[i][j]=a[i][j-1]; else a[i][j]=a[i-value[j]][j]+1;//相当于把乘法换成加法,即碰到一个钱数于 兑换货币自身价值时,返回到 钱数减去该货币值的地方,其值再加 1// }//for } cout<<""兑换的最小货币个数是:""<