首页 > 编程语言 >八种经典排序算法

八种经典排序算法

时间:2024-10-18 09:51:20浏览次数:7  
标签:int void 算法 八种 length static array 排序

以下是八种经典排序算法的介绍,包括它们的基本思想、时间复杂度、稳定性以及代码示例:

1. 插入排序

  • 基本思想:每步将一个待排序的元素按其关键码值的大小插入到前面已经排序的部分中,直到全部插入完为止。
  • 时间复杂度:最坏和平均情况为O(n²),最佳情况为O(n)(当数据基本有序时)。
  • 稳定性:稳定的排序方法。
  • 代码示例
     
    public static void insertionSort(int[] array) {  
        int tmp;  
        for (int i = 1; i < array.length; i++) {  
            tmp = array[i];  
            int j = i;  
            for (; j > 0 && array[j - 1] > tmp; j--) {  
                array[j] = array[j - 1];  
            }  
            array[j] = tmp;  
        }  
    }

2. 冒泡排序

  • 基本思想:持续比较相邻的元素,如果第一个比第二个大,就交换它们,直到没有任何一对数字需要比较。
  • 时间复杂度:最坏和平均情况为O(n²),最佳情况为O(n)(当数据已经有序时)。
  • 稳定性:稳定的排序方法。
  • 代码示例
     
    public static void bubbleSort(int[] array) {  
        int tmp;  
        boolean flag;  
        for (int i = array.length - 1; i >= 0; i--) {  
            flag = false;  
            for (int j = 0; j < i; j++) {  
                if (array[j] > array[j + 1]) {  
                    tmp = array[j];  
                    array[j] = array[j + 1];  
                    array[j + 1] = tmp;  
                    flag = true;  
                }  
            }  
            if (!flag) break; // 如果没有发生交换,排序完成  
        }  
    }

3. 选择排序

  • 基本思想:每次从待排序的数据中选出最小(或最大)的元素,存放在序列的起始位置,直到全部排完。
  • 时间复杂度:O(n²)。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void selectSort(int[] array) {  
        for (int i = 0; i < array.length - 1; i++) {  
            int min = array[i];  
            int minindex = i;  
            for (int j = i; j < array.length; j++) {  
                if (array[j] < min) {  
                    min = array[j];  
                    minindex = j;  
                }  
            }  
            if (i != minindex) {  
                array[minindex] = array[i];  
                array[i] = min;  
            }  
        }  
    }

4. 希尔排序

  • 基本思想:先取一个小于n的整数作为增量,将数据分组并进行插入排序,逐步减小增量,直到增量为1时进行最后的插入排序。
  • 时间复杂度:依赖于增量序列,通常为O(n log n)到O(n²)之间。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void shellSort(int[] array) {  
        int n = array.length;  
        for (int gap = n / 2; gap > 0; gap /= 2) {  
            for (int i = gap; i < n; i++) {  
                int temp = array[i];  
                int j;  
                for (j = i; j >= gap && array[j - gap] > temp; j -= gap) {  
                    array[j] = array[j - gap];  
                }  
                array[j] = temp;  
            }  
        }  
    }

5. 归并排序

  • 基本思想:将数组分成两半,分别对两半进行排序,然后合并已排序的两半。
  • 时间复杂度:O(n log n)。
  • 稳定性:稳定的排序方法。
  • 代码示例
     
    public static void mergeSort(int[] array) {  
        if (array.length < 2) return;  
        int mid = array.length / 2;  
        int[] left = Arrays.copyOfRange(array, 0, mid);  
        int[] right = Arrays.copyOfRange(array, mid, array.length);  
        mergeSort(left);  
        mergeSort(right);  
        merge(array, left, right);  
    }  
    
    private static void merge(int[] array, int[] left, int[] right) {  
        int i = 0, j = 0, k = 0;  
        while (i < left.length && j < right.length) {  
            if (left[i] <= right[j]) {  
                array[k++] = left[i++];  
            } else {  
                array[k++] = right[j++];  
            }  
        }  
        while (i < left.length) array[k++] = left[i++];  
        while (j < right.length) array[k++] = right[j++];  
    }

6. 快速排序

  • 基本思想:选择一个基准元素,将数组分成两部分,左边部分小于基准,右边部分大于基准,然后递归排序这两部分。
  • 时间复杂度:最坏情况为O(n²),平均情况为O(n log n)。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void quickSort(int[] array, int low, int high) {  
        if (low < high) {  
            int pivotIndex = partition(array, low, high);  
            quickSort(array, low, pivotIndex - 1);  
            quickSort(array, pivotIndex + 1, high);  
        }  
    }  
    
    private static int partition(int[] array, int low, int high) {  
        int pivot = array[high];  
        int i = low - 1;  
        for (int j = low; j < high; j++) {  
            if (array[j] < pivot) {  
                i++;  
                int temp = array[i];  
                array[i] = array[j];  
                array[j] = temp;  
            }  
        }  
        int temp = array[i + 1];  
        array[i + 1] = array[high];  
        array[high] = temp;  
        return i + 1;  
    }

7. 堆排序

  • 基本思想:利用堆这种数据结构,首先构建一个最大堆,然后将堆顶元素与最后一个元素交换,缩小堆的大小并重新调整堆,直到排序完成。
  • 时间复杂度:O(n log n)。
  • 稳定性:不稳定的排序方法。
  • 代码示例
     
    public static void heapSort(int[] array) {  
        int n = array.length;  
        for (int i = n / 2 - 1; i >= 0; i--) {  
            heapify(array, n, i);  
        }  
        for (int i = n - 1; i > 0; i--) {  
            int temp = array[0];  
            array[0] = array[i];  
            array[i] = temp;  
            heapify(array, i, 0);  
        }  
    }  
    
    private static void heapify(int[] array, int n, int i) {  
        int largest = i;  
        int left = 2 * i + 1;  
        int right = 2 * i + 2;  
        if (left < n && array[left] > array[largest]) {  
            largest = left;  
        }  
        if (right < n && array[right] > array[largest]) {  
            largest = right;  
        }  
        if (largest != i) {  
            int swap = array[i];  
            array[i] = array[largest];  
            array[largest] = swap;  
            heapify(array, n, largest);  
        }  
    }

8. 计数排序

  • 基本思想:通过统计每个元素出现的次数,然后根据计数结果直接将元素放入正确的位置。
  • 时间复杂度:O(n + k),其中n是待排序元素的数量,k是元素值的范围。
  • 稳定性:稳定的排序方法。
  • 代码示例
    public static void countingSort(int[] array) {  
        int max = Arrays.stream(array).max().getAsInt();  
        int[] count = new int[max + 1];  
        for (int num : array) {  
            count[num]++;  
        }  
        int index = 0;  
        for (int i = 0; i < count.length; i++) {  
            while (count[i] > 0) {  
                array[index++] = i;  
                count[i]--;  
            }  
        }  
    }

这些排序算法各有特点,适用于不同的场景和数据规模。在实际应用中,选择合适的排序算法可以显著提高程序的效率。掌握这些算法对于编程和面试都非常重要。

标签:int,void,算法,八种,length,static,array,排序
From: https://blog.csdn.net/qq_25699299/article/details/143034931

相关文章

  • 格点拉格朗日插值与PME算法
    技术背景在前面的一篇博客中,我们介绍了拉格朗日插值法的基本由来和表示形式。这里我们要介绍一种拉格朗日插值法的应用场景:格点拉格朗日插值法。这种场景的优势在于,如果我们要对整个实数空间进行求和或者积分,计算量是随着变量的形状增长的。例如分子动力学模拟中计算静电势能,光是......
  • 传统特征算法——人脸识别
    人脸识别是目前人工智能领域中成熟较早、落地较广的技术之一,广泛应用于手机解锁、支付验证、安防布控等多个领域。其核心在于通过特定的算法识别图像或视频中人脸的身份,这一过程的实现离不开特征算法的支持。以下是对人脸识别特征算法的详细介绍:一、人脸识别系统概述一个......
  • Leetcode刷题. 贪心算法
    贪心算法:    比较传统的解释:将整个问题拆解为几个小问题,找到小问题的最优解,加起来就是整个问题的全局最优解。对于现在的我理解贪心就是一种感觉,给出证明很难,解题思路一般就是认真读题,发掘题目的条件,然后尝试给出算法。11.盛最多水的容器     一个显而易......
  • [算法日常] 逆序对
    [算法日常]逆序对定义在一个长度为\(n\)的数组\(a\)中,若存在\(\forall1\lei,j\len\),使得\(a_i>a_j\),则称\(<a_i,a_j>\)为一对逆序对。举个例子,一个长度为\(5\)的数组为:15364则存在\(3\)个逆序对,分别是\(<5,3>,<5,4>,<6,4>\)。解法F1:显然,可以枚举......
  • STL容器和算法
    1、C++的STL介绍(内存管理、allocator、函数、实现机理、多线程实现)STL一共提供六大组件,包括容器、算法、迭代器、仿函数、配接器和配置器,彼此可以组合套用。容器通过配置器取得数据存储空间,算法通过迭代器存取容器内容,仿函数可以协助算法完成不同的策略变化,配接器可以应用于容......
  • 武汉大学卫星导航算法程序设计——解码与数据获取
    还在为解码发愁吗?面对二进制文件还是无从下手吗?一篇文章帮你搞定。我们从接收机获取的数据并不是rinex格式的文件,而是NovAtel数据格式的二进制文件。我们需要从文件中提取出我们需要的导航数据,也就是解码的过程。废话不多说,我们直接开始讲解。一、Binary数据头格式请不要使......
  • 排序算法 - 快速排序
    排序算法-快速排序  概要  快速排序(Quicksort)是对冒泡排序算法的一种改进。快速排序是一种基于分而治之的排序算法。  它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按......
  • 【算法】C++中的二分查找
    ......
  • 代码随想录算法训练营 | 1143.最长公共子序列,1035.不相交的线,53. 最大子序和,392.判断
    1143.最长公共子序列题目链接:1143.最长公共子序列文档讲解︰代码随想录(programmercarl.com)视频讲解︰最长公共子序列日期:2024-10-17想法:这里的子序列不要求连续了,dp[i][j]要表示为在text1[0,i-1]和text2[0,j-1]的范围里,最长的公共子序列长度,-1同样是为了初始化方便,如果te......
  • 吴恩达深度学习笔记(4)---加速神经网络训练速度的优化算法
    机器学习的应用是一个高度依赖经验,不断重复的过程,需要训练很多模型才能找到一个确实好用的。小批量梯度下降算法:矢量化可以有效计算m个算例而不需要for循环,因此我们需要将所有的训练样例放入巨型矩阵中。但是当数据量超大时,计算时间仍需很久,可以考虑将训练集分为微小的训练集......