选择排序
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
算法步骤
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕
C++实现
#include <iostream> #include <vector> template <typename T>void selection_sort (std::vector<T>& arr) { for (int i = 0 ; i < arr.size () - 1 ; i++) { int min = i; for (int j = i + 1 ; j < arr.size (); j++) if (arr[j] < arr[min]) min = j; std::swap (arr[i], arr[min]); } } int main () { std::vector<int > arr1 = {10 , 7 , 8 , 9 , 1 , 5 }; selection_sort (arr1); std::cout << "Sorted array (int): " ; for (int i = 0 ; i < arr1.size (); i++) std::cout << arr1[i] << " " ; std::cout << std::endl; std::vector<float > arr2 = {3.14 , 2.71 , 1.618 , 0.707 , 2.718 }; selection_sort (arr2); std::cout << "Sorted array (float): " ; for (int i = 0 ; i < arr2.size (); i++) std::cout << arr2[i] << " " ; std::cout << std::endl; return 0 ; }
时间复杂度 O(n^2),需要遍历每个元素
空间复杂度O(1),不占用额外空间
快速排序
快速排序是一种使用分治策略的排序算法。它选择一个元素作为“枢纽”或“基准”元素,然后将数组分为两个子数组——一个包含所有比基准元素小的元素,另一个包含所有比基准元素大的元素。然后对这两个子数组进行递归地快速排序。
算法步骤
从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
C++实现:
#include <iostream> using namespace std;int Partition (int A[], int low, int high) { int pivot = A[low]; while (low < high) { while (low < high && A[high] >= pivot) { --high; } A[low] = A[high]; while (low < high && A[low] <= pivot) { ++low; } A[high] = A[low]; } A[low] = pivot; return low; } void QuickSort (int A[], int low, int high) { if (low < high) { int pivot = Partition (A, low, high); QuickSort (A, low, pivot - 1 ); QuickSort (A, pivot + 1 , high); } } int main () { int arr[] = {10 , 7 , 8 , 9 , 1 , 5 }; int n = sizeof (arr) / sizeof (arr[0 ]); QuickSort (arr, 0 , n - 1 ); std::cout << "Sorted array: " ; for (int i = 0 ; i < n; i++) { std::cout << arr[i] << " " ; } std::cout << std::endl; return 0 ; }
C++11优化随机快排
class Solution {private : void qSort (vector<int >& nums, int leftBorder, int rightBorder) { if (leftBorder >= rightBorder) return ; int pivot = leftBorder + rand () % (rightBorder - leftBorder + 1 ); swap (nums[pivot], nums[leftBorder]); int left = leftBorder, right = rightBorder; int pivotNum = nums[leftBorder]; while (left < right) { while (left < right && nums[right] >= pivotNum) --right; nums[left] = nums[right]; while (left < right && nums[left] <= pivotNum) ++left; nums[right] = nums[left]; } nums[left] = pivotNum; while (left>0 && nums[left] == nums[left-1 ]) --left; while (right< nums.size ()-1 && nums[right] == nums[right+1 ]) ++right; qSort (nums, leftBorder,left-1 ); qSort (nums, right+1 , rightBorder); } public : vector<int > sortArray (vector<int >& nums) { srand ((unsigned )time (NULL )); qSort (nums, 0 , (int )nums.size () - 1 ); return nums; } }
时间空间复杂度分析