左旋字符串的应用 百度面试

来源:互联网 发布:黑莓passport视频软件 编辑:程序博客网 时间:2024/04/30 08:50

转自 http://blog.csdn.net/hackbuteer1/article/details/7542774

4、数组al[0,mid-1]和al[mid,num-1]是各自有序的,对数组al[0,num-1]的两个子有序段进行merge,得到al[0,num-1]整体有序。要求空间复杂度为O(1)。注:al[i]元素是支持'<'运算符的。

/*数组a[begin, mid] 和 a[mid+1, end]是各自有序的,对两个子段进行Merge得到a[begin , end]的有序数组。 要求空间复杂度为O(1)方案:1、两个有序段位A和B,A在前,B紧接在A后面,找到A的第一个大于B[0]的数A[i], A[0...i-1]相当于merge后的有效段,在B中找到第一个大于A[i]的数B[j],对数组A[i...j-1]循环右移j-k位,使A[i...j-1]数组的前面部分有序2、如此循环merge3、循环右移通过先子段反转再整体反转的方式进行,复杂度是O(L), L是需要循环移动的子段的长度*/#include<iostream>using namespace std;void Reverse(int *a , int begin , int end )   //反转{for(; begin < end; begin++ , end--)swap(a[begin] , a[end]);}void RotateRight(int *a , int begin , int end , int k)    //循环右移{int len = end - begin + 1;  //数组的长度k %= len;Reverse(a , begin , end - k);Reverse(a , end - k + 1 , end);Reverse(a , begin , end);}// 将有序数组a[begin...mid] 和 a[mid+1...end] 进行归并排序void Merge(int *a , int begin , int end ){int i , j , k;i = begin;j = 1 + ((begin + end)>>1);    //位运算的优先级比较低,外面需要加一个括号,刚开始忘记添加括号,导致错了很多次while(i <= end && j <= end && i<j){while(i <= end && a[i] < a[j])i++;k = j;   //暂时保存指针j的位置while(j <= end && a[j] < a[i])j++;if(j > k)RotateRight(a , i , j-1 , j-k);   //数组a[i...j-1]循环右移j-k次i += (j-k+1);  //第一个指针往后移动,因为循环右移后,数组a[i....i+j-k]是有序的}}void MergeSort(int *a , int begin , int end ){if(begin == end)return ;int mid = (begin + end)>>1;MergeSort(a , begin , mid);   //递归地将a[begin...mid] 归并为有序的数组MergeSort(a , mid+1 , end);   //递归地将a[mid+1...end] 归并为有序的数组Merge(a , begin , end);       //将有序数组a[begin...mid] 和 a[mid+1...end] 进行归并排序}int main(void){int n , i , a[20];while(cin>>n){for(i = 0 ; i < n ; ++i)cin>>a[i];MergeSort(a , 0 , n - 1);for(i = 0 ; i < n ; ++i)cout<<a[i]<<" ";cout<<endl;}return 0;}


 

原创粉丝点击