01 排序算法汇总
常见经典排序算法可以分为两大类:一类是比较类排序
即通过比较两元素的大小来决定它们的相对次序,比如:快排、冒泡排序、归并排序、堆排序、选择排序、插入排序、希尔排序等;另一类试是非比较类排序
即不通过比较两元素的大小来决定它们的相对次序,比如:计数排序、桶排序、基数排序。
比较类排序
快速排序
快排是很重要的排序算法,面试常常让我们手撕快排代码。快排的基本思想:通过一趟排序将待排元素分隔成独立的两部分,其中一部分元素均比另一部分的元素小,接着分别递归下去对这两部分元素继续进行排序,以达到整个序列有序。
/*
快排属于分治算法,分治算法都有三步:
1. 分成子问题
2. 递归处理子问题
3. 子问题合并
*/
// c++ 代码实现
void quick_sort(int arr[], int l, int r)
{
//递归的终止情况
if(l >= r) return;
//第一步:分成子问题
int i = l - 1, j = r + 1, x = arr[l + r >> 1];
while(i < j)
{
do i++; while(arr[i] < x);
do j--; while(arr[j] > x);
if(i < j) swap(arr[i], arr[j]);
}
//第二步:递归处理子问题
quick_sort(arr, l, j), quick_sort(arr, j + 1, r);
//第三步:子问题合并.快排这一步不需要操作,但归并排序的核心在这一步骤
}
// java代码实现
void quickSort(int[] arr, int l, int r)
{
//递归的终止情况
if(l >= r) return;
//第一步:分成子问题
int i = l - 1, j = r + 1, x = arr[l + r >> 1];
while(i < j)
{
do i++; while(arr[i] < x);
do j--; while(arr[j] > x);
if(i < j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
//第二步:递归处理子问题
quickSort(arr, l, j), quickSort(arr, j + 1, r);
//第三步:子问题合并.快排这一步不需要操作,但归并排序的核心在这一步骤
}
冒泡排序
void bubble_sort(int arr[], int n) {
// n :数组长度
if (n < 2) return;
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) swap(arr[j], arr[j+1]);
}
}
}
归并排序
void merge_sort(int arr[], int l, int r)
{
//递归的终止情况
if(l >= r) return;
//第一步:分成子问题
int mid = l + r >> 1;
//第二步:递归处理子问题
merge_sort(arr, l, mid ), merge_sort(arr, mid + 1, r);
//第三步:合并子问题
int k = 0, i = l, j = mid + 1, tmp[r - l + 1];
while(i <= mid && j <= r)
if(arr[i] <= arr[j]) tmp[k++] = arr[i++];
else tmp[k++] = arr[j++];
while(i <= mid) tmp[k++] = arr[i++];
while(j <= r) tmp[k++] = arr[j++];
for(k = 0, i = l; i <= r; k++, i++) arr[i] = tmp[k];
}