首页 > 编程语言 >七大基于比较的排序算法

七大基于比较的排序算法

时间:2024-07-24 21:54:19浏览次数:11  
标签:Sort int 复杂度 七大 算法 array 排序

目录

一、基于比较的排序算法概述

1. 插入排序(Insertion Sort)

2. 选择排序(Selection Sort)

3. 冒泡排序(Bubble Sort)

4. 归并排序(Merge Sort)

5. 快速排序(Quick Sort)

6. 堆排序(Heap Sort)

7. 希尔排序(Shell Sort)

二、排序算法的性能分析

三、Java中的常用排序方法


  在计算机科学中,排序算法是处理数据结构的核心算法之一。它不仅直接影响程序的性能,还影响到数据的传输和存储效率。本文将深入探讨七种基于比较的排序算法,包括它们的基本原理、实现方法和性能分析,同时也会介绍Java中常用的排序方法。

一、基于比较的排序算法概述

  基于比较的排序算法是指通过比较元素之间的大小关系来确定元素的排列顺序的算法。这类算法的时间复杂度下界为O(n log n)。根据不同的策略和实现,常见的基于比较的排序算法包括插入排序、选择排序、冒泡排序、归并排序、快速排序、堆排序以及希尔排序。以下对这七种排序算法进行详细介绍。

1. 插入排序(Insertion Sort)


原理

插入排序是一种简单且直观的排序算法。它通过构建一个有序的序列,将待排序的元素逐步插入到已排序序列中,直到所有元素都在正确的位置。

实现

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

  性能分析

插入排序的时间复杂度为O(n²),适合小规模数据的排序。其空间复杂度为O(1),是一个原地排序算法。对几乎已经排序的数据集,其性能接近O(n)。

2. 选择排序(Selection Sort)


原理

选择排序通过反复选择未排序部分的最小元素,逐步将其放到已排序部分的末尾。

实现

public static void selectionSort(int[] array) {  
    for (int i = 0; i < array.length - 1; i++) {  
        int minIndex = i;  
        for (int j = i + 1; j < array.length; j++) {  
            if (array[j] < array[minIndex]) {  
                minIndex = j;  
            }  
        }  
        int temp = array[minIndex];  
        array[minIndex] = array[i];  
        array[i] = temp;  
    }  
}  

性能分析

选择排序的时间复杂度为O(n²),空间复杂度为O(1)。它不适合大规模数据排序,因为在最坏情况下仍然需要n²的比较次数。

3. 冒泡排序(Bubble Sort)


原理

  冒泡排序通过重复遍历待排序的元素,比较相邻元素并根据大小关系进行交换,直到没有元素需要交换为止。

实现

public static void bubbleSort(int[] array) {  
    int n = array.length;  
    for (int i = 0; i < n - 1; i++) {  
        for (int j = 0; j < n - 1 - i; j++) {  
            if (array[j] > array[j + 1]) {  
                int temp = array[j];  
                array[j] = array[j + 1];  
                array[j + 1] = temp;  
            }  
        }  
    }  
}  

性能分析

  冒泡排序的时间复杂度为O(n²),空间复杂度为O(1)。尽管实现简单,但由于其性能性能较差,通常不用于实际应用。

4. 归并排序(Merge Sort)


原理

  归并排序采用分治法,将待排序数组分成两个子数组,分别对其进行排序后再合并成一个有序数组。实现

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

性能分析

  归并排序的时间复杂度为O(n log n),空间复杂度为O(n)。由于其稳定性和较优的性能,常用于大规模数据排序。

5. 快速排序(Quick Sort)


原理

快速排序也采用分治法,通过选择一个“基准”元素,将数组分成小于和大于基准的两个部分,递归地对这两个部分进行排序。实现

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

性能分析

  快速排序的平均时间复杂度为O(n log n),最坏情况为O(n²)(如已经有序数组),空间复杂度为O(log n)。快速排序在大多数情况下表现优秀,尤其适用于大规模数据排序。

6. 堆排序(Heap Sort)


原理

堆排序利用堆结构  以确定元素的顺序。首先构建一个最大堆,将堆顶元素与最后一个元素交换,缩小堆并调整已构建的堆。实现

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

性能分析

  堆排序的时间复杂度为O(n log n),空间复杂度为O(1)。由于其不稳定性,使用场景受到一定限制。

7. 希尔排序(Shell Sort)


原理

希尔排序是插入排序的一种改进版,通过使用间隔进行分组,实现对每组内的元素进行插入排序,从而最终达到整体有序。

实现

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

性能分析

  希尔排序的时间复杂度取决于间隔序列的选择,通常在O(n log n)与O(n²)之间。具有不稳定性,适用于中等规模的数据排序。

二、排序算法的性能分析

排序算法的性能分析主要从时间复杂度和空间复杂度两个方面进行。

  时间复杂度:描述算法执行所需时间与输入规模之间的关系。大多数已知的排序算法都具有O(n²)和O(n log n)的时间复杂度,差别主要体现在算法的实际常数因子以及适用的输入规模和分布特征。
  空间复杂度:描述算法执行所需额外存储空间与输入规模之间的关系。原地排序算法(如堆排序、快速排序)在空间复杂度方面表现优异,而归并排序等需要额外存储空间的算法则性能较差,适用于内存充足的情况。


三、Java中的常用排序方法

  在Java中,除了自定义实现的排序算法外,Java Collections框架也提供了多种高效的排序方法。例如,Arrays.sort()和Collections.sort()分别用于数组和集合的排序。这些排序方法通常使用的是优化后的快速排序算法,性能优越且易于使用。

Arrays.sort(array); // 数组排序  
Collections.sort(list); // 集合排序  


  此外,在Java 8及其之后的版本中引入了并行流(parallel streams),以支持并行排序,通过更好地利用多核处理器资源来提高排序性能。

标签:Sort,int,复杂度,七大,算法,array,排序
From: https://blog.csdn.net/XHgga_/article/details/140621467

相关文章

  • C++ 插入排序
    【预告】        这几次将讲讲排序(从简单开始),废话不多说,直接切入正题【关于插入排序】【定义】    定义:插入排序是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入【时间复杂度】 ......
  • 算法介绍(一):LLCNN低光照
    对于一张灰度图片,像素值越大则亮度越高,像素值越小则亮度越低在数字图像处理领域有一种很简单的图像亮度调整算法——伽马变换伽马变换是一种用于调整图像亮度和对比度的非线性操作,其基本公式为(I'=I^\gamma),其中(I')是输出图像的灰度值,(I)是输入图像的灰度值,而(\g......
  • java中的一些经典算法code
    //1.importjava.util.LinkedList;importjava.util.Queue;publicclassCandyGame{//定义一个点的类,用于记录位置和当前累计的糖果数量staticclassPoint{intx,y,steps,candies;Point(intx,inty,intsteps,intcandies){......
  • 改进的灰狼优化算法(GWO)(附完整matlab代码)
    1.灰狼优化算法灰狼优化算法作为一种高效率群体智能优化算法,其结构简单,收敛速度快,调节参数少,在时间序列预测,机械设计,结构设计,聚类分析等工程问题上都有着十分广泛的应用。但是在应用过程中发现,其存在种群多样性差,后期收敛速度缓慢,容易陷入局部最优以及局部搜索和全局搜索不均......
  • 2024 | 大模型算法工程师相关面试题汇总及答案解析
    前言在准备大模型的面试时,我们需要对模型的基础理论、进阶应用、微调策略、以及特定技术如LangChain、参数高效微调(PEFT)等有深入的理解。这里给大家整理了一份详细的面试题,帮助大家提前进行面试复习,同时对自己的技术进行查漏补缺。一、大模型基础面试题目前主流的开源模......
  • 算法笔记|Day6哈希表基础II
    算法笔记|Day6哈希表基础II☆☆☆☆☆leetcode454.四数相加II题目分析代码☆☆☆☆☆leetcode383.赎金信题目分析代码☆☆☆☆☆leetcode15.三数之和题目分析代码☆☆☆☆☆leetcode18.四数之和题目分析代码☆☆☆☆☆leetcode454.四数相加II题目链接:leetco......
  • 数据结构与算法,剑指Offer 50题
    队列队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。对列的添加insertappend队列的取值列表[-1]列表[0]队列的删......
  • MVO-CNN多输入分类预测|多元宇宙算法-卷积神经网络|Matlab
    目录一、程序及算法内容介绍:基本内容:亮点与优势:二、实际运行效果三、算法介绍:四、完整程序下载:一、程序及算法内容介绍:基本内容:本代码基于Matlab平台编译,将MVO(多元宇宙算法)与CNN(卷积神经网络)结合,进行多输入数据分类预测输入训练的数据包含12个特征,1个响应值,即......
  • Python实现RSA加密算法,让你的信息更加安全
    一、什么是编码    想要实现加密就必须要先了解什么是编码。    编码是信息从另一种形式或格式转换为另一种形式或格式的过程,解码则是编码的逆过程。字符编码(CharacterEncoding)是把字符集中的字符编码为指定集合中的某个对象,以便信息在计算机中传输。在密码......
  • 「代码随想录算法训练营」第十九天 | 回溯算法 part01
    回溯算法模板voidbacktracking(参数){if(终止条件){存放结果;return;}for(选择:本层集合中元素(树中节点孩子的数量就是集合的大小)){处理节点;backtracking(路径,选择列表);//递归回溯,撤销处理结果}}......