数据结构-快速排序
1、快速排序(最好的内排序)
1)在待排序的元素任取一个元素作为基准(通常选第一个元素,但最好的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
2)将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
3)对左右两个分区重复以上步骤直到所有元素都是有序的。
#include <stdio.h> #include <stdlib.h> void swap(int k[], int low, int high) { int temp = k[low]; k[low] = k[high]; k[high] = temp; } //交换顺序表中子表顺序,返回枢纽所在的位置,此时在枢纽之前(不大于)后(不小于) int Partition(int k[], int low, int high) { int pivotkey; pivotkey = k[low]; //枢纽选取为第一个元素 while (low < high) { while (low < high && k[high] >= pivotkey)//将右侧比枢纽小的值,调整至低端 high--; swap(k, low, high); while (low < high && k[low] <= pivotkey)//将左侧比枢纽大的值,调整至高端 low++; swap(k, low, high); } return low;//此时low=high,返回枢纽所在位置 } void QuickSort(int k[], int low, int high) { int pivot; if (low < high) { pivot = Partition(k, low, high); QuickSort(k, low, pivot - 1); //对枢纽左侧递归排序 QuickSort(k, pivot + 1, high); //对枢纽右侧递归排序 } } int main() { int i; int a[10] = { 5, 2, 6, 0, 3, 9, 1, 7, 4, 8 }; QuickSort(a, 0, 9); for (i = 0; i < 10; i++) printf_s("%d ", a[i]); return 1; }
改进1:三数取中,取三个关键字先解析排序,将中间数作为枢轴,一般取左端,右端和中间三个数
如果我们选取的枢轴值正好是处于整个序列大小的中间位置,那么可以将序列分为小数集合和大数集合。但是若是我们第一个选取的是最大值呢?我们交换后实质变化并不大
int Partition(int k[], int low, int high) { int pivotkey; int m = low + (high - low) / 2; //三数取中的判断 if (k[low] > k[high]) swap(k, low, high); if (k[m] > k[high]) swap(k, m, high); if (k[m] < k[low]) swap(k, m, low); //此时m处是三个数中间值 pivotkey = k[m]; //用子表第一个记录左枢轴记录 while (low < high) //从表的两端交替向中间扫描 { while (low < high && k[high] >= pivotkey) high--; swap(k, high, low); //将比枢轴记录小的记录交换到低端 while (low < high && k[low] <= pivotkey) low++; swap(k, low, high); //将比枢轴记录大的记录交换到高端 } return low; //返回枢轴所在位置 }
改进二、优化小数组:当数组非常小时,使用快排还不如直接插入的性能好,二这个数组大小的阈值我们一般选取7最好
#define MAX_LENGTH_INSERT_SORT 7 //数组阈值大小 void InsertSort(int k[], int n) //对数组部分进行快排 { int i, j, temp; for (i = 1; i < n;i++) { if (k[i]<k[i-1]) { temp = k[i]; for (j = i - 1; k[j] > temp; j--) k[j + 1] = k[j]; k[j + 1] = temp; } } } void Qsort(int k[], int low, int high) { int pivot; if ((high-low)>MAX_LENGTH_INSERT_SORT) //条件是包含high>low { pivot = Partition(k, low, high); Qsort(k, low, pivot - 1); //对低子表进行递归排序 Qsort(k, pivot + 1, high); //对高子表进行递归排序 } else { InsertSort(k + low, high - low + 1); //对数组部分进行快排 } }