交换排序
冒泡排序
传统方法:
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.