001-快速排序(C++实现)
快速排序的基本实现
快速排序算法是一种基于交换的高效的排序算法,它采用了分治法的思想:
1、从数列中取出一个数作为基准数(枢轴,pivot)。
2、将数组进行划分(partition),将比基准数大的元素都移至枢轴右边,将小于等于基准数的元素都移至枢轴左边。
3、再对左右的子区间重复第二步的划分操作,直至每个子区间只有一个元素。
快排最重要的一步就是划分了。划分的过程用通俗的语言讲就是“挖坑”和“填坑”。
快速排序时间复杂度
快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)。
这句话很好理解:假设被排序的数列中有N个数。遍历一次的时间复杂度是O(N),需要遍历多少次呢?至少lg(N+1)次,最多N次。
(01) 为什么最少是lg(N+1)次?快速排序是采用的分治法进行遍历的,我们将它看作一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。
因此,快速排序的遍历次数最少是lg(N+1)次。
(02) 为什么最多是N次?这个应该非常简单,还是将快速排序看作一棵二叉树,它的深度最大是N。因此,快读排序的遍历次数最多是N次。
快速排序稳定性
快速排序是不稳定的算法,它不满足稳定算法的定义。
算法稳定性 — 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
快速排序 实现一:
1 int partition(int arr[], int left, int right) //找基准数 划分 2 { 3 int i = left + 1 ; 4 int j = right; 5 int temp = arr[left]; 6 7 while(i <= j) 8 { 9 while (arr[i] < temp) 10 { 11 i++; 12 } 13 while (arr[j] > temp ) 14 { 15 j--; 16 } 17 if (i < j) 18 swap(arr[i++], arr[j--]); 19 else i++; 20 } 21 swap(arr[j], arr[left]); 22 return j; 23 24 } 25 26 void quick_sort(int arr[], int left, int right) 27 { 28 if (left > right) 29 return; 30 int j = partition(arr, left, right); 31 quick_sort(arr, left, j - 1); 32 quick_sort(arr, j + 1, right); 33 }
快速排序 实现方法二:
1 void QuickSort(int array[], int start, int last) 2 { 3 int i = start; 4 int j = last; 5 int temp = array[i]; 6 if (i < j) 7 { 8 while (i < j) 9 { 10 // 11 while (i < j && array[j]>=temp ) 12 j--; 13 if (i < j) 14 { 15 array[i] = array[j]; 16 i++; 17 } 18 19 while (i < j && temp > array[i]) 20 i++; 21 if (i < j) 22 { 23 array[j] = array[i]; 24 j--; 25 } 26 27 } 28 //把基准数放到i位置 29 array[i] = temp; 30 //递归方法 31 QuickSort(array, start, i - 1); 32 QuickSort(array, i + 1, last); 33 } 34 }
快速排序 用C++函数模板实现
1 template<typename T> 2 void quicksort(T data[], int first, int last) 3 { 4 int lower = first + 1; 5 int upper = last; 6 swap(data[first], data[(first + last) / 2]); 7 T bound = data[first]; 8 while (lower <= upper) 9 { 10 while (data[lower] < bound) 11 lower++; 12 while (data[upper] > bound) 13 upper--; 14 if (lower < upper) 15 swap(data[lower++], data[upper--]); 16 else lower++; 17 } 18 swap(data[upper], data[first]); 19 if (first < upper - 1) 20 quicksort(data, first, upper - 1); 21 if (upper + 1 < last) 22 quicksort(data, upper + 1, last); 23 } 24 25 template<class T> 26 void quicksort(T data[], int n) 27 { 28 int i, max; 29 if (n < 2) 30 return; 31 for (i = 1, max = 0; i < n; i++) 32 if (data[max] < data[i]) 33 max = i; 34 swap(data[n - 1], data[max]); 35 quicksort(data, 0, n - 2); // 36 }
快速排序 主函数测试代码
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <algorithm> #include <time.h> using namespace std; void PrintArray(int array[], int len) { for (int i = 0; i < len; i++) { cout << array[i] << " "; } cout << endl; } int main(void) { const int NUM = 10; int array[NUM] = { 0 }; srand((unsigned int)time(nullptr)); for (int i = 0; i < NUM; i++) { array[i] = rand() % 100 + 1; } cout << "排序前:" << endl; PrintArray(array, NUM); cout << "排序后:" << endl; quicksort(array, 0, NUM - 1); PrintArray(array, NUM); return 0; }