有些人说 归并排序的递归版本实用性差 可读性强
非递归版本恰好相反
我觉得 也没那么明显差距吧....
其实非递归版本也不难理解的
假如 我们需要进行排序的数组的长度为 len 每次的子排序数组区间为size
那么我们首先将它拆成 len个size为1的小区间 然后2个相邻的进行合并merge排序 这时候 你需要判断一下 能否恰好一一合并 因为是奇数就不行了
这样 我们进行了第一趟归并 然后size*2 然后将size为2的2个相邻区间进行合并 继续判断..
一直到size>len 结束循环
...
然后这题 我分别拿 递归的归并 非递归的归并进行了测试 没什么区别
其中 对于归并中的辅助数组我们可以选择直接开好足够大的静态数组 或者选择 new[right-left+1]来开 当然 我们也知道new的话会比较耗时 但同时也节省了内存
************************
差点忘记说这题了 毫无特色=-= 或许是因为我做了上一题的原因 只要你能读懂英文...#24 就是完全一样的啊...
1 #include <iostream> 2 using namespace std; 3 4 typedef long long LL; 5 LL sum; 6 const int size = 1000010; 7 int arr[size]; 8 int temp[size]; 9 10 void merge_sort( int l , int r ) 11 { 12 int p , q , mid , i; 13 if( r-l > 1 ) 14 { 15 p = l; 16 mid = l + (r-l)/2; 17 q = mid; 18 i = l; 19 merge_sort( l , mid ); 20 merge_sort( mid , r ); 21 while( p<mid || q<r ) 22 { 23 if( q>=r || ( p<mid && arr[p]<=arr[q]) ) 24 { 25 temp[i++] = arr[p++]; 26 } 27 else 28 { 29 temp[i++] = arr[q++]; 30 sum += mid-p; 31 } 32 } 33 for( i = l ; i < r ; i++ ) 34 arr[i] = temp[i]; 35 } 36 } 37 38 int main() 39 { 40 cin.sync_with_stdio(false); 41 int n; 42 while( cin >> n ) 43 { 44 sum = 0; 45 for( int i = 0 ; i<n ; i++ ) 46 cin >> arr[i]; 47 merge_sort( 0 , n ); 48 cout << sum << endl; 49 } 50 return 0; 51 }
1 #include <iostream> 2 using namespace std; 3 4 typedef long long LL; 5 LL sum; 6 const int size = 1000010; 7 int arr[size]; 8 int temp[size]; 9 10 void merge( int left , int mid , int right ) 11 { 12 int p , q , i; 13 p = i = left , q = mid+1; 14 while( p<=mid || q<=right ) 15 { 16 if( q>right || ( p<=mid && arr[p]<=arr[q] ) ) 17 { 18 temp[i++] = arr[p++]; 19 } 20 else 21 { 22 temp[i++] = arr[q++]; 23 sum += mid-p+1; 24 } 25 } 26 for( i = left ; i<=right ; i++ ) 27 { 28 arr[i] = temp[i]; 29 } 30 } 31 32 void merge_sort( int n ) 33 { 34 int left , mid , right , len; 35 len = 1; 36 while( len <= n-1 ) 37 { 38 left = 0; 39 while( left+len <= n-1 ) 40 { 41 mid = left + len - 1; 42 right = mid + len; 43 if( right>n-1 ) 44 right = n-1; 45 merge( left , mid , right ); 46 left = right + 1; 47 } 48 len *= 2; 49 } 50 } 51 52 int main() 53 { 54 cin.sync_with_stdio(false); 55 int n; 56 while( cin >> n ) 57 { 58 sum = 0; 59 for( int i = 0 ; i<n ; i++ ) 60 { 61 cin >> arr[i]; 62 } 63 merge_sort( n ); 64 cout << sum << endl; 65 } 66 return 0; 67 }
1 #include <iostream> 2 using namespace std; 3 4 typedef long long LL; 5 LL sum; 6 const int size = 1000010; 7 int arr[size]; 8 9 void merge( int left , int mid , int right ) 10 { 11 int p , q , i; 12 p = left , q = mid+1; 13 int* temp = new int[right-left+1]; 14 i = 0; 15 while( p<=mid || q<=right ) 16 { 17 if( q>right || ( p<=mid && arr[p]<=arr[q] ) ) 18 { 19 temp[i++] = arr[p++]; 20 } 21 else 22 { 23 temp[i++] = arr[q++]; 24 sum += mid-p+1; 25 } 26 } 27 for( int k = 0 , i = left ; i<=right ; i++ , k++ ) 28 { 29 arr[i] = temp[k]; 30 } 31 delete []temp; 32 } 33 34 void merge_sort( int n ) 35 { 36 int left , mid , right , len; 37 len = 1; 38 while( len <= n-1 ) 39 { 40 left = 0; 41 while( left+len <= n-1 ) 42 { 43 mid = left + len - 1; 44 right = mid + len; 45 if( right>n-1 ) 46 right = n-1; 47 merge( left , mid , right ); 48 left = right + 1; 49 } 50 len *= 2; 51 } 52 } 53 54 int main() 55 { 56 cin.sync_with_stdio(false); 57 int n; 58 while( cin >> n ) 59 { 60 sum = 0; 61 for( int i = 0 ; i<n ; i++ ) 62 { 63 cin >> arr[i]; 64 } 65 merge_sort( n ); 66 cout << sum << endl; 67 } 68 return 0; 69 }
today:
寒门出贵子,
白屋出公卿。
将相本无种,
男儿当自强。
时间: 2024-11-05 07:18:15