我要好offer之 排序算法大总结
1. 插入排序
(1) 直接插入排序
void StraightInsertionSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; for (int i = 1; i < num.size(); ++i) { int tmp = num.at(i); int j = i - 1; for (; j >= 0 && num.at(j) > tmp; --j) { num.at(j + 1) = num.at(j); } num.at(j + 1) = tmp; } }
(2) 折半插入排序
void BinaryInsertionSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; for (int i = 1; i < num.size(); ++i) { int tmp = num.at(i); int first = 0; // 最终的first值即为插入位置 int last = i - 1; while (first <= last) { int mid = first + (last - first) / 2; if (num.at(mid) < tmp) { first = mid + 1; } else if (num.at(mid) > tmp) { last = mid - 1; } else { first = mid; break; } } for (int t = i - 1; t >= first; --t) { num.at(t + 1) = num.at(t); } num.at(first) = tmp; } }
2. 希尔排序
void ShellSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; for (int gap = num.size() / 2; gap > 0; gap /= 2) { for (int i = gap; i < num.size(); ++i) { for (int j = i - gap; j >= 0 && num.at(j) > num.at(j + gap); j -= gap) { std::swap(num.at(j), num.at(j + gap)); } } } }
3. 冒泡排序
void BubbleSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; for (int i = 0; i < num.size(); ++i) { for (int j = 0; j < num.size() - i - 1; ++j) { if (num.at(j) > num.at(j + 1)) { std::swap(num.at(j), num.at(j + 1)); } } } }
4. 快速排序
(1) 递归版
// 划分 int Partition(std::vector<int>& num, int first, int last) { assert(first >= 0 && first < num.size() && last >= 0 && last < num.size() && first <= last); int mid = first + (last - first) / 2; std::swap(num.at(first), num.at(mid)); int pos = first; for (int i = first; i <= last; ++i) { if (num.at(i) < num.at(first)) { std::swap(num.at(++pos), num.at(i)); } } std::swap(num.at(first), num.at(pos)); return pos; } // 快速排序 void quickSort(std::vector<int>& num, int first, int last) { if (first < last) { int pivotPos = Partition(num, first, last); quickSort(num, first, pivotPos - 1); quickSort(num, pivotPos + 1, last); } } void QuickSort(std::vector<int>& num) { quickSort(num, 0, num.size() - 1); }
(2) 非递归版
int Partition(std::vector<int>& num, int first, int last) { assert(first >= 0 && first < num.size() && last >= 0 && last < num.size() && first <= last); int mid = first + (last - first) / 2; std::swap(num.at(first), num.at(mid)); int pos = first; for (int i = first; i <= last; ++i) { if (num.at(i) < num.at(first)) { std::swap(num.at(++pos), num.at(i)); } } std::swap(num.at(first), num.at(pos)); return pos; } void QuickSort(std::vector<int>& num, int first, int last) { if (first < last) { std::stack<int> stk; int pivotPos = Partition(num, first, last); if (first < pivotPos - 1) { stk.push(first); stk.push(pivotPos - 1); } if (last > pivotPos + 1) { stk.push(pivotPos + 1); stk.push(last); } while (!stk.empty()) { int right = stk.top(); stk.pop(); int left = stk.top(); stk.pop(); pivotPos = Partition(num, left, right); if (left < pivotPos - 1) { stk.push(left); stk.push(pivotPos - 1); } if (right > pivotPos + 1) { stk.push(pivotPos + 1); stk.push(right); } } } }
5. 简单选择排序
void SimpleSelectSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; for (int i = 0; i < num.size(); ++i) { for (int j = i + 1; j < num.size(); ++j) { if (num.at(j) < num.at(i)) { std::swap(num.at(i), num.at(j)); } } } }
6. 堆排序
// 堆调整,注意结点编号kth从1开始 void HeapAdjust(std::vector<int>& num, int kth, int vecSize) { int left = 2 * kth; int right = 2 * kth + 1; int largest = INT_MIN; if (left <= vecSize && num.at(left - 1) > num.at(kth - 1)) { largest = left; } else { largest = kth; } if (right <= vecSize && num.at(right - 1) > num.at(largest - 1)) { largest = right; } if (largest != kth) { std::swap(num.at(kth - 1), num.at(largest - 1)); HeapAdjust(num, largest, vecSize); } } // 建堆 void BuildHeap(std::vector<int>& num) { for (int i = num.size() / 2; i >= 0; --i) { HeapAdjust(num, i + 1, num.size()); } } // 堆排序 void HeapSort(std::vector<int>& num) { BuildHeap(num); int vecSize = num.size(); while (vecSize > 1) { std::swap(num.at(0), num.at(vecSize - 1)); --vecSize; HeapAdjust(num, 1, vecSize); } }
7. 归并排序
void merge(std::vector<int>& num, int first, int mid, int last) { std::vector<int> tmp(last - first + 1, 0); int i = first; int j = mid + 1; int idx = 0; while (i <= mid && j <= last) { if (num.at(i) <= num.at(j)) { tmp.at(idx++) = num.at(i++); } else { tmp.at(idx++) = num.at(j++); } } while (i <= mid) { tmp.at(idx++) = num.at(i++); } while (j <= last) { tmp.at(idx++) = num.at(j++); } for (int i = first; i <= last; ++i) { num.at(i) = tmp.at(i - first); } } void MergeSort(std::vector<int>& num, int first, int last) { if (first < last) { int mid = first + (last -first) / 2; MergeSort(num, first, mid); MergeSort(num, mid + 1, last); merge(num, first, mid, last); } }
8. 计数排序
void CountSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; int minVal = *(std::min_element(num.begin(), num.end())); int maxVal = *(std::max_element(num.begin(), num.end())); int valRange = maxVal - minVal + 1; std::vector<int> count(valRange, 0); for (int i = 0; i < num.size(); ++i) { count.at(num.at(i) - minVal)++; } for (int i = 1; i < count.size(); ++i) { count.at(i) = count.at(i) + count.at(i - 1); } std::vector<int> tmp(num); for (int i = tmp.size() - 1; i >= 0; --i) { int lessNum = count.at(tmp.at(i) - minVal); num.at(lessNum - 1) = tmp.at(i); count.at(tmp.at(i) - minVal)--; } }
小结: