当前位置: 首页 > article >正文

算法基础之八大排序

文章目录

    • 概要
    • 1. 冒泡排序(Bubble Sort)
    • 2. 选择排序(Selection Sort)
    • 3. 插入排序(Insertion Sort)
    • 4. 希尔排序(Shell Sort)
    • 5. 归并排序(Merge Sort)
    • 6. 快速排序(Quick Sort)
    • 7. 堆排序(Heap Sort)
    • 8. 计数排序(Counting Sort)
  • 小结

概要

排序算法是编程中最基础也是最重要的算法之一。通过学习和理解不同的排序算法,我们可以在实际开发中选择合适的算法来解决问题。本文将介绍八大常用排序算法,并分别用 Python、C++ 和 Java 三种语言实现。


时间复杂度

1. 冒泡排序(Bubble Sort)

算法描述: 冒泡排序是一种简单的排序算法,通过不断交换相邻元素,使得较大的元素“浮”到数组的末尾。

时间复杂度

  • 最佳情况:O(n)
  • 平均情况:O(n²)
  • 最坏情况:O(n²)

空间复杂度: O(1)
稳定性: 稳定

实现步骤

  1. 比较相邻元素,前大则交换

  2. 对每一对相邻元素重复操作

  3. 每次遍历后范围缩小1

  4. 重复直到无交换发生

代码实现

python版本

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

C++版本

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (arr[j] > arr[j+1]) {
                // Swap elements
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

Java版本

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n-1; i++) {
            for (int j = 0; j < n-i-1; j++) {
                if (arr[j] > arr[j+1]) {
                    // Swap elements
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}

2. 选择排序(Selection Sort)

算法描述: 选择排序通过分为有序区和无序区,逐步从无序区中找到最小元素,放到有序区的末尾。

时间复杂度:

  • 最佳情况:O(n²)
  • 平均情况:O(n²)
  • 最坏情况:O(n²)

空间复杂度: O(1)

稳定性: 不稳定

代码实现
python版本

# Python
def bubble_sort(arr):
    n = len(arr)
    for i in range(n-1):
        swapped = False
        for j in range(n-1-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = True
        if not swapped:
            break
    return arr

C++版本

// C++
void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n-1; ++i) {
        bool swapped = false;
        for (int j = 0; j < n-1-i; ++j) {
            if (arr[j] > arr[j+1]) {
                swap(arr[j], arr[j+1]);
                swapped = true;
            }
        }
        if (!swapped) break;
    }
}

Java版本

// Java
public static void bubbleSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n-1; i++) {
        boolean swapped = false;
        for (int j = 0; j < n-1-i; j++) {
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                swapped = true;
            }
        }
        if (!swapped) break;
    }
}

3. 插入排序(Insertion Sort)

算法思想: 将未排序元素逐个插入已排序序列的合适位置

时间复杂度:

  • 平均:O(n²)

  • 最坏:O(n²)

  • 最好:O(n)

稳定性: 稳定

python版本

# Python
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j >=0 and key < arr[j] :
            arr[j+1] = arr[j]
            j -= 1
        arr[j+1] = key
    return arr

C++版本

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

Java版本

// Java
public static void insertionSort(int[] arr) {
    for (int i = 1; i < arr.length; ++i) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = key;
    }
}

4. 希尔排序(Shell Sort)

算法思想: 改进的插入排序,通过间隔分组进行预处理
时间复杂度: O(n log n) ~ O(n²)
稳定性: 不稳定

python版本

# 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++版本

// C++
void shellSort(int arr[], int n) {
    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;
        }
    }
}

Java版本

// Java
public static void shellSort(int[] arr) {
    int n = arr.length;
    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;
        }
    }
}

5. 归并排序(Merge Sort)

算法思想: 分治法,递归拆分后合并有序子序列
时间复杂度: O(n log n)
稳定性: 稳定

python版本

# Python
def merge_sort(arr):
    if len(arr) > 1:
        mid = len(arr)//2
        L = arr[:mid]
        R = arr[mid:]
        merge_sort(L)
        merge_sort(R)
        
        i = j = k = 0
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1
        
        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1
        
        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1
    return arr

C++版本:

// C++
void merge(int arr[], int l, int m, int r) {
    int n1 = m - l + 1;
    int n2 = r - m;
    int L[n1], R[n2];
    
    for (int i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (int j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];
    
    int i = 0, j = 0, k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }
    
    while (i < n1) arr[k++] = L[i++];
    while (j < n2) arr[k++] = R[j++];
}

void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        int m = l + (r - l)/2;
        mergeSort(arr, l, m);
        mergeSort(arr, m+1, r);
        merge(arr, l, m, r);
    }
}

Java版本

// Java
public static void mergeSort(int[] arr, int l, int r) {
    if (l < r) {
        int m = (l + r) / 2;
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);
        
        int[] L = Arrays.copyOfRange(arr, l, m + 1);
        int[] R = Arrays.copyOfRange(arr, m + 1, r + 1);
        
        int i = 0, j = 0, k = l;
        while (i < L.length && j < R.length) {
            if (L[i] <= R[j]) arr[k++] = L[i++];
            else arr[k++] = R[j++];
        }
        while (i < L.length) arr[k++] = L[i++];
        while (j < R.length) arr[k++] = R[j++];
    }
}

6. 快速排序(Quick Sort)

算法思想: 分治法,选取基准元素进行分区排序
时间复杂度:

  • 平均:O(n log n)

  • 最坏:O(n²)

稳定性: 不稳定

python版本

在这里插入代码片# Python
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr)//2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

C++版本:

// C++
int partition(int arr[], int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i+1], arr[high]);
    return i+1;
}

void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi-1);
        quickSort(arr, pi+1, high);
    }
}

Java版本

// Java
public static void quickSort(int[] arr, int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi-1);
        quickSort(arr, pi+1, high);
    }
}

private static int partition(int[] arr, int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    int temp = arr[i+1];
    arr[i+1] = arr[high];
    arr[high] = temp;
    return i+1;
}

7. 堆排序(Heap Sort)

算法思想: 利用堆数据结构进行选择排序
时间复杂度: O(n log n)
稳定性: 不稳定

python版本

# Python
def heapify(arr, n, i):
    largest = i
    l = 2 * i + 1
    r = 2 * i + 2
    if l < n and arr[l] > arr[largest]:
        largest = l
    if r < n and arr[r] > arr[largest]:
        largest = r
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)
    for i in range(n//2-1, -1, -1):
        heapify(arr, n, i)
    for i in range(n-1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)
    return arr

C++版本:

// C++
void heapify(int arr[], int n, int i) {
    int largest = i;
    int l = 2*i + 1;
    int r = 2*i + 2;
    
    if (l < n && arr[l] > arr[largest])
        largest = l;
    if (r < n && arr[r] > arr[largest])
        largest = r;
        
    if (largest != i) {
        swap(arr[i], arr[largest]);
        heapify(arr, n, largest);
    }
}

void heapSort(int arr[], int n) {
    for (int i = n/2 - 1; i >= 0; i--)
        heapify(arr, n, i);
        
    for (int i = n-1; i > 0; i--) {
        swap(arr[0], arr[i]);
        heapify(arr, i, 0);
    }
}

Java版本

// Java
public static void heapSort(int[] arr) {
    int n = arr.length;
    for (int i = n/2 - 1; i >= 0; i--)
        heapify(arr, n, i);
        
    for (int i = n-1; i > 0; i--) {
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;
        heapify(arr, i, 0);
    }
}

private static void heapify(int[] arr, int n, int i) {
    int largest = i;
    int l = 2*i + 1;
    int r = 2*i + 2;
    
    if (l < n && arr[l] > arr[largest]) largest = l;
    if (r < n && arr[r] > arr[largest]) largest = r;
    
    if (largest != i) {
        int swap = arr[i];
        arr[i] = arr[largest];
        arr[largest] = swap;
        heapify(arr, n, largest);
    }
}

8. 计数排序(Counting Sort)

适用场景: 整数排序且值范围不大
时间复杂度: O(n + k)
稳定性: 稳定

python版本

# Python
def counting_sort(arr):
    max_val = max(arr)
    count = [0] * (max_val + 1)
    
    for num in arr:
        count[num] += 1
    
    idx = 0
    for i in range(len(count)):
        while count[i] > 0:
            arr[idx] = i
            idx += 1
            count[i] -= 1
    return arr

C++版本:

// C++
void countingSort(int arr[], int n) {
    int maxVal = *max_element(arr, arr + n);
    int count[maxVal + 1] = {0};
    
    for (int i = 0; i < n; i++)
        count[arr[i]]++;
        
    int idx = 0;
    for (int i = 0; i <= maxVal; i++) {
        while (count[i]-- > 0) {
            arr[idx++] = i;
        }
    }
}

Java版本

// Java
public static void countingSort(int[] arr) {
    int maxVal = Arrays.stream(arr).max().getAsInt();
    int[] count = new int[maxVal + 1];
    
    for (int num : arr) count[num]++;
    
    int idx = 0;
    for (int i = 0; i <= maxVal; i++) {
        while (count[i]-- > 0) {
            arr[idx++] = i;
        }
    }
}

小结

排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序O(n²)O(n²)O(1)稳定
选择排序O(n²)O(n²)O(1)不稳定
插入排序O(n²)O(n²)O(1)稳定
希尔排序O(n log n)O(n²)O(1)不稳定
归并排序O(n log n)O(n log n)O(n)稳定
快速排序O(n log n)O(n²)O(log n)不稳定
堆排序O(n log n)O(n log n)O(1)不稳定
计数排序O(n + k)O(n + k)O(k)稳定

注:k为计数排序的值域范围

应用场景建议:

  • 小规模数据:插入排序

  • 通用高效:快速排序

  • 内存敏感:堆排序

  • 稳定需求:归并排序

  • 整数排序:计数排序


http://www.kler.cn/a/539163.html

相关文章:

  • 【AI学习】LLM的发展方向
  • 安卓开发,底部导航栏
  • win32汇编环境,对线程的创建与操作示例一
  • Json-RPC框架项目(一)
  • 数据源和 sqlSessionFactory 配置
  • DFS+回溯+剪枝(深度优先搜索)——搜索算法
  • C++设计模式 —— 工厂模式
  • Docker 部署 MinIO | 国内阿里镜像
  • vLLM V1 重磅升级:核心架构全面革新
  • DeepSeek结合Langchain的基本用法
  • 卷积神经网络CNN如何处理语音信号
  • 2025年物联网相关专业毕业论文选题参考,文末联系,选题相关资料提供
  • 学生管理系统
  • Qt元对象系统
  • C++排序算法的优劣及应用
  • 通过cad中块获取块的略缩图——cad c# 二次开发
  • C++ 继承(1)
  • 常用线程池
  • 【安当产品应用案例100集】037-强化OpenVPN安全防线的卓越之选——安当ASP身份认证系统
  • ASP.NET Core数据校验FluentValidation
  • 车联网技术在智能交通系统中的设计与实现(论文+源码)
  • “图像识别分割算法:解锁视觉智能的关键技术
  • 【c++】面向过程 面向对象
  • 苍穹外卖-菜品分页查询
  • C# 多线程应用(同步异步)
  • 《 C++ 点滴漫谈: 二十六 》控制流艺术:如何在 C++ 中驾驭程序逻辑