归并排序及拓展
- 请在较短的时间内写出归并排序的程序。
- 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组, 求出该数组中的逆序对的总数。
1、思路:
二叉树后序遍历的思想,即先递归排序左右子树,然后才是根节点。时间复杂度O(nlogn),空间复杂度O(n)。
MergeSort
1 #include <stdio.h> 2 #include <assert.h> 3 4 void PrintArray(int* data, int length) 5 { 6 for (int i = 0; i < length; i++) 7 printf("%d ", data[i]); 8 printf("\n"); 9 } 10 11 static int MergeArray(int* data, int left, int mid, int right) 12 { 13 int length = right - left + 1; 14 int* temp = new int[length]; 15 int i = left; 16 int j = mid + 1; 17 int t = 0; 18 while (i <= mid && j <= right) 19 { 20 if (data[i] > data[j]) 21 temp[t++] = data[j++]; 22 else 23 temp[t++] = data[i++]; 24 } 25 for (; i <= mid; i++) 26 temp[t++] = data[i]; 27 for (; j <= right; j++) 28 temp[t++] = data[j]; 29 for (int k = 0; k < length; k++) 30 { 31 data[left] = temp[k]; 32 left++; 33 } 34 delete[] temp; 35 } 36 37 void MergeSort(int *data, int left, int right) 38 { 39 assert(data); 40 if (left >= right) 41 return; 42 int mid = (left + right) / 2; 43 MergeSort(data, left, mid); 44 MergeSort(data, mid + 1, right); 45 MergeArray(data, left, mid, right); 46 } 47 48 49 int main() 50 { 51 int test[7] = {23, 13, 49, 6, 31, 19, 28}; 52 PrintArray(test, 7); 53 MergeSort(test, 0, 6); 54 PrintArray(test, 7); 55 }
2、思路:
参考归并排序思路,只是在合并的时候返回来,从后往前比较,当左边的数大于右边的数,则计数往上加(右边递归结束是排完序的,所以说右边之前的数都要小于该数)。
InversePairs
1 #include <stdio.h> 2 #include <assert.h> 3 4 void PrintArray(int* data, int length) 5 { 6 for (int i = 0; i < length; i++) 7 printf("%d ", data[i]); 8 printf("\n"); 9 } 10 11 static int MergePairs(int* data, int left, int mid, int right) 12 { 13 int length = right - left + 1; 14 int* temp = new int[length]; 15 int i = mid; 16 int j = right; 17 int t = length - 1; 18 int count = 0; 19 while (i >= left && j >= mid + 1) 20 { 21 if (data[i] > data[j]) 22 { 23 temp[t--] = data[i--]; 24 count += j - mid; 25 } 26 else 27 temp[t--] = data[j--]; 28 } 29 30 for (; i >= left; i--) 31 temp[t--] = data[i]; 32 for (; j >= mid + 1; j--) 33 temp[t--] = data[j]; 34 for (int k = 0; k < length; k++) 35 data[left++] = temp[k]; 36 delete[] temp; 37 return count; 38 } 39 40 int InversePairs(int* data, int left, int right) 41 { 42 assert(data); 43 if (left >= right) 44 return 0; 45 int mid = (left + right) / 2; 46 int lc = InversePairs(data, left, mid); 47 int rc = InversePairs(data, mid + 1, right); 48 int mc = MergePairs(data, left, mid, right); 49 return lc + rc + mc; 50 } 51 52 int main() 53 { 54 int test[4] = {5, 6, 4, 3}; 55 PrintArray(test, 4); 56 int result = InversePairs(test, 0, 3); 57 PrintArray(test, 4); 58 printf("%d\n", result); 59 }
3、思路:
参考:http://zhedahht.blog.163.com/