交换排序
冒泡排序
传统方法:
for (int i = 0; i < numsSize - 1; i++) {for (int j = 0; j < numsSize - 1 - i; j++) {if (nums[j] > nums[j + 1]) {Swap(&nums[j], &nums[j + 1]);}}
}
方法二:
while循环+for循环
int end = numsSize - 1;
while (end >= 0) {int flag = 0;for (int j = 0; j < end; j++) {if (nums[j] > nums[j + 1]) {Swap(&nums[j], &nums[j + 1]);flag = 1;}}if (flag == 0) break;--end;
}
快速排序
快排的核心是分治。
找到一个pivot.
左边比它小,有别比它大,一直递归,直到数组有序。
找pivot有三种方法:
int PartSort1(int* nums, int left, int right) {int index = GetMidIndex(nums, left, right);Swap(&nums[left], &nums[right]);int begin = left, end = right;int pivot = begin;int key = nums[begin];while (begin < end) {//右边找小,放到左边while (begin < end && nums[end] >= key) {--end;}//小的放到左边的坑里,自己形成新的坑位nums[pivot] = nums[end];pivot = end;while (begin < end && nums[begin] <= key) {++begin;}nums[pivot] = nums[begin];pivot = begin;}pivot = begin;nums[pivot] = key;return pivot;
}
end找小,begin找大,找到之后调用交换函数,最后begin和end重合,执行Swap(&nums[begin], &nums[keyi]);
int PartSort2(int* nums, int left, int right) {int index = GetMidIndex(nums, left, right);Swap(&nums[left], &nums[right]);int begin = left, end = right;int keyi = nums[begin];while (begin < end) {//找小while (begin < end && nums[end] >= nums[keyi]) {--end;}//找大while (begin < end && nums[begin] <= nums[keyi]) {++begin;}Swap(&nums[begin], &nums[end]);}Swap(&nums[begin], &nums[keyi]);return begin;}
int PartSort3(int* nums, int left, int right) {int index = GetMidIndex(nums, left, right);Swap(&nums[left], &nums[index]);int keyi = left;int prev = left, cur = left + 1;while (cur <= right) {if (nums[cur] < nums[keyi]) {++prev;Swap(&nums[prev], &nums[cur]);}++cur;}Swap(&nums[prev], &nums[keyi]);return prev;
}
快排存在一种最坏的情况,及一串数有序时,左别没有比pivot那个位置小的数。
需要一直找。
时间复杂度将变为O(n*n)
故需要通过三数取中来排除最坏的情况。
int GetMidIndex(int* nums, int left,int right) {int mid = (left + right) >> 1;if (nums[left] < nums[mid]) {if (nums[mid] < nums[right]) {return mid;}else if (nums[left] > nums[right]) {return left;}else {return right;}}else {//nums[left] > nums[mid]if (nums[mid] < nums[right]) {return right;}else if (nums[left] < nums[right]) {return left;}else {return mid;}}}
void QuickSort(int* nums, int left,int right) {if (left >= right) {return;}int keyIndex = PartSort3(nums, left, right);if (keyIndex - 1 - left > 10) {QuickSort(nums,left, keyIndex -1);}else {InsertSort(nums + left, keyIndex - 1 - left + 1);}if (right - (keyIndex + 1) > 10) {QuickSort(nums, keyIndex + 1, right);}else {InsertSort(nums + keyIndex + 1, right - (keyIndex + 1) + 1);}}
数据量小与10时使用InsertSort可以提高效率、
if{
}
else{
}
的目的是为了小区间优化。
进一步提高效率。
2^10=1024.