排序一次讲清(从冒泡到基数)


【待更新】
引用

冒泡

原理

如果我们想要让数组从左至右从小到大排序,可以在左边比右边数字大的时候让它们进行交换,只需要重复地进行直到没有再需要交换,这样就可以保证没有左边比右边数字大,即数列已经排序完成。
由于每次循环后最大的数字必然在最右边,因为如果有比它小的数字就会进行交换,所以必然在不超过 O ( n 2 ) O(n^2) O(n2)时间内完成。最优情况为当输入的数据是正序时 O ( n ) O(n) O(n)最坏情况*当输入的数据是反序时 O ( n 2 ) O(n^2) O(n2)
由于数字会像泡泡一样缓缓冒到顶端,所以就叫冒泡排序。

比如说以[3,1,2]为例
首先由于3>1,所以交换,变成[1,3,2]
接着由于3>2,所以交换,变成[1,2,3]
接着由于1<2,无事发生,保持[1,2,3]
完成排序

代码

python

def bubbleSort(arr):
    for i in range(1, len(arr)):
        for j in range(0, len(arr)-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

c++

#include <iostream>
using namespace std;
template<typename T> 
void bubble_sort(T arr[], int len) {
	int i, j;
    for (i = 0; i < len - 1; i++){
		for (j = 0; j < len - 1 - i; j++){
			if (arr[j] > arr[j + 1])
				swap(arr[j], arr[j + 1]);
		}
	}
}

选择

原理

首先找到数组中最小的数字,将其与最左边数字交换;然后再找第二小的数字与第二个数字交换……直到最后一个数字。
其实由于每次循环最小数字都会在最左边,所以其实可以抛弃已经排好序了的。但是由于每次找最小数字都要 O ( n ) O(n) O(n)时间,n个数字,所以复杂度一直都为 O ( n 2 ) O(n^2) O(n2)

代码

python

def selectionSort(arr):
    for i in range(len(arr) - 1):
        # 记录最小数的索引
        minIndex = i
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[minIndex]:
                minIndex = j
        # i 不是最小数时,将 i 和最小数进行交换
        if i != minIndex:
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
    return arr

c++

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]);
        }
}

插入

原理

对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。也就是说,从第一个元素开始(该元素可以认为已经被排序)取出下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置。重复直到找到已排序的元素小于或者等于新元素的位置。不难看出序列左端一直是保持有序的。
平均情况和最坏情况下都是 O ( n 2 ) O(n^2) O(n2),最好情况也就是已经排好序了时是 O ( n ) O(n) O(n)

代码

python

def insertionSort(arr):
    for i in range(len(arr)):
        preIndex = i-1
        current = arr[i]
        while preIndex >= 0 and arr[preIndex] > current:
            arr[preIndex+1] = arr[preIndex]
            preIndex-=1
        arr[preIndex+1] = current
    return arr

c++

void insertion_sort(int arr[], int len) {
    for (int i = 1; i < len; i++) {
        int key = arr[i];
        int j = i - 1;
        
        while (j >= 0 && key < arr[j]) {
            arr[j + 1] = arr[j];
            j--;
        }
        
        arr[j + 1] = key;
    }
}

希尔

原理

也称为缩小增量排序,是插入排序的一种更高效的改进版本。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;

希尔排序的基本思想是:先选择一个增量序列,通常从n/2开始。再根据当前增量,将数组分成若干组,每组包含相隔增量的元素。对每组内部的元素进行插入排序。将增量减小为原来的一半或某个其他因子,重复直到增量减小到1。当增量为1时,整个数组将被视为一组,进行一次插入排序,完成排序。

代码

python

def shell_sort(arr):
    n = len(arr)
    gap = n // 2

    # 初始化增量序列
    while gap > 0:
        for i in range(gap, n):
            temp = arr[i]
            j = i
            # 对每组进行插入排序
            while j >= gap and arr[j - gap] > temp:
                arr[j] = arr[j - gap]
                j -= gap
            arr[j] = temp
        gap //= 2

    return arr

c++

void shellSort(std::vector<int>& arr) {
    int n = arr.size();
    for (int gap = n / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < n; i++) {
            int temp = arr[i];
            int j;
            // 对子序列进行插入排序
            for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
                arr[j] = arr[j - gap];
            }
            arr[j] = temp;
        }
    }
}

快排

原理

代码

python

c++


归并

原理

代码

python

c++


原理

代码

python

c++


计数

原理

代码

python

c++


原理

代码

python

c++


基数

原理

代码

python


c++


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值