首页 > 其他分享 >八大基础排序

八大基础排序

时间:2024-05-28 18:55:05浏览次数:20  
标签:arr 八大 int 基础 num static 排序 public

八大基础排序

1. 冒泡排序(Bubble Sort)

基本思想:依次比较相邻的两个元素,若它们的顺序错误则进行交换。
特点:稳定排序,但效率较低,时间复杂度为O(n^2),空间复杂度为O(1)。

代码实例

public class BubbleSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用冒泡排序对数组进行排序  
        bubbleSort(arr);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 冒泡排序方法  
    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 - i - 1; j++) {  
                // 交换如果元素找到比下一个元素大  
                if (arr[j] > arr[j + 1]) {  
                    // 交换元素  
                    int temp = arr[j];  
                    arr[j] = arr[j + 1];  
                    arr[j + 1] = temp;  
                    // 如果有交换,则标记为true  
                    swapped = true;  
                }  
            }  
            // 如果没有交换发生,说明数组已经有序  
            if (!swapped) {  
                break;  
            }  
        }  
    }  
}

2. 选择排序(Selection Sort)

基本思想:在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。
特点:不稳定排序,时间复杂度为O(n^2),空间复杂度为O(1)。

实例代码

public class SelectionSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用选择排序对数组进行排序  
        selectionSort(arr);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 选择排序方法  
    public static void selectionSort(int[] arr) {  
        int n = arr.length;  
        for (int i = 0; i < n - 1; i++) {  
            // 找到剩余部分中的最小元素  
            int minIndex = i;  
            for (int j = i + 1; j < n; j++) {  
                if (arr[j] < arr[minIndex]) {  
                    minIndex = j;  
                }  
            }  
            // 将找到的最小元素与第一个未排序的元素交换  
            if (minIndex != i) {  
                int temp = arr[minIndex];  
                arr[minIndex] = arr[i];  
                arr[i] = temp;  
            }  
        }  
    }  
}

3. 插入排序(Insertion Sort)

基本思想:将待排序的数据分成已排序和未排序两部分,每次将一个元素插入到已排序部分的正确位置。
特点:稳定排序,时间复杂度为O(n^2),空间复杂度为O(1)。

实例代码

public class InsertionSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用插入排序对数组进行排序  
        insertionSort(arr);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 插入排序方法  
    public static void insertionSort(int[] arr) {  
        int n = arr.length;  
        for (int i = 1; i < n; i++) {  
            int key = arr[i]; // 要插入的元素  
            int j = i - 1;  
  
            // 将比key大的元素向后移动  
            while (j >= 0 && arr[j] > key) {  
                arr[j + 1] = arr[j];  
                j = j - 1;  
            }  
            arr[j + 1] = key; // 将key插入到正确的位置  
        }  
    }  
}

4. 快速排序(Quick Sort)

基本思想:通过一趟排序将待排记录分割为独立的两个部分,其中一部分记录的关键字均比另一部分的关键字小,然后对这两部分记录继续进行排序,以达到整个序列有序。
特点:不稳定排序,但效率较高,时间复杂度为O(nlogn),空间复杂度为O(logn)。

示例代码

public class QuickSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用快速排序对数组进行排序  
        quickSort(arr, 0, arr.length - 1);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 快速排序方法  
    public static void quickSort(int[] arr, int low, int high) {  
        if (low < high) {  
            // pi是分区索引,arr[p]现在已经到位  
            int pi = partition(arr, low, high);  
  
            // 分别对分区前后部分进行排序  
            quickSort(arr, low, pi - 1);  
            quickSort(arr, pi + 1, high);  
        }  
    }  
  
    // 分区操作  
    public static int partition(int[] arr, int low, int high) {  
        int pivot = arr[high];    // 选择最右边的元素作为轴点  
        int i = (low - 1);  // 最小元素索引  
  
        for (int j = low; j <= high - 1; j++) {  
            // 如果当前元素小于或等于轴点  
            if (arr[j] <= pivot) {  
                i++;    // 递增索引  
                // 交换 arr[i] 和 arr[j]  
                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;  
    }  
}

5. 归并排序(Merge Sort)

基本思想:将两个或两个以上的有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的,然后再把有序子序列合并为整体有序序列。
特点:稳定排序,时间复杂度为O(nlogn),但空间复杂度较高,为O(n)。

public class MergeSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用归并排序对数组进行排序  
        arr = mergeSort(arr, 0, arr.length - 1);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 归并排序方法  
    public static int[] mergeSort(int[] arr, int left, int right) {  
        if (left < right) {  
            // 找到中间索引  
            int mid = left + (right - left) / 2;  
  
            // 对左半部分进行归并排序  
            arr = mergeSort(arr, left, mid);  
  
            // 对右半部分进行归并排序  
            arr = mergeSort(arr, mid + 1, right);  
  
            // 合并两个已排序的部分  
            merge(arr, left, mid, right);  
        }  
        return arr;  
    }  
  
    // 合并两个已排序的部分  
    public static void merge(int[] arr, int left, int mid, int right) {  
        int n1 = mid - left + 1;  
        int n2 = right - mid;  
  
        // 创建临时数组  
        int[] L = new int[n1];  
        int[] R = new int[n2];  
  
        // 复制数据到临时数组  
        for (int i = 0; i < n1; ++i)  
            L[i] = arr[left + i];  
        for (int j = 0; j < n2; ++j)  
            R[j] = arr[mid + 1 + j];  
  
        // 合并临时数组到arr[left..right]  
        int i = 0, j = 0, k = left;  
        while (i < n1 && j < n2) {  
            if (L[i] <= R[j]) {  
                arr[k] = L[i];  
                i++;  
            } else {  
                arr[k] = R[j];  
                j++;  
            }  
            k++;  
        }  
  
        // 复制L[]的剩余元素  
        while (i < n1) {  
            arr[k] = L[i];  
            i++;  
            k++;  
        }  
  
        // 复制R[]的剩余元素  
        while (j < n2) {  
            arr[k] = R[j];  
            j++;  
            k++;  
        }  
    }  
}

6. 堆排序(Heap Sort)

基本思想:利用堆这种数据结构的特性,首先将待排序的数据构建成一个最大(或最小)堆,然后将堆顶元素与最后一个元素交换,并重新调整堆,这样就得到了最大(或最小)值。重复这个过程直到所有数据元素有序。
特点:不稳定排序,但效率较高,时间复杂度为O(nlogn),空间复杂度为O(1)。

public class HeapSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用堆排序对数组进行排序  
        heapSort(arr);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 堆排序方法  
    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--) {  
            // 将当前最大的元素arr[0]和arr[i]交换  
            int temp = arr[0];  
            arr[0] = arr[i];  
            arr[i] = temp;  
  
            // 重新对剩下的元素进行堆化  
            heapify(arr, i, 0);  
        }  
    }  
  
    // 堆化方法  
    public static void heapify(int[] arr, int n, int i) {  
        int largest = i; // 初始化最大值为根  
        int left = 2 * i + 1; // 左子节点  
        int right = 2 * i + 2; // 右子节点  
  
        // 如果左子节点比根大  
        if (left < n && arr[left] > arr[largest]) {  
            largest = left;  
        }  
  
        // 如果右子节点比当前最大的还大  
        if (right < n && arr[right] > arr[largest]) {  
            largest = right;  
        }  
  
        // 如果最大元素不是根  
        if (largest != i) {  
            // 交换  
            int swap = arr[i];  
            arr[i] = arr[largest];  
            arr[largest] = swap;  
  
            // 递归堆化受影响的子树  
            heapify(arr, n, largest);  
        }  
    }  
}

7. 希尔排序(Shell Sort)

基本思想:先将整个待排记录序列分割为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

实例代码

public class ShellSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
  
        // 使用希尔排序对数组进行排序  
        shellSort(arr);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 希尔排序方法  
    public static void shellSort(int[] arr) {  
        int n = arr.length;  
        int gap = n / 2; // 初始间隔  
  
        // 动态定义间隔序列  
        while (gap > 0) {  
            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;  
            }  
  
            // 更新间隔  
            gap /= 2;  
        }  
    }  
}

特点:不稳定排序,是插入排序的一种更高效的改进版本,时间复杂度依赖于增量序列的选择。

8. 基数排序(Radix Sort)

基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。
特点:稳定排序,适用于整数排序,时间复杂度取决于整数的位数和采用的基数。

示例代码

public class RadixSortExample {  
    public static void main(String[] args) {  
        // 示例数组  
        int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};  
  
        // 使用基数排序对数组进行排序  
        radixSort(arr);  
  
        // 输出排序后的数组  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
  
    // 基数排序方法  
    public static void radixSort(int[] arr) {  
        // 找到数组中的最大数  
        int max = findMax(arr);  
  
        // 获取最大数的位数  
        int maxDigit = getMaxDigit(max);  
  
        // 初始化临时数组  
        int[][] temp = new int[10][arr.length];  
        int[] count = new int[10]; // 用于计数  
  
        // 对每一位进行排序  
        for (int i = 1; i <= maxDigit; i++) {  
            // 将数组元素分配到临时数组  
            for (int j = 0; j < arr.length; j++) {  
                int digit = getDigit(arr[j], i);  
                temp[digit][count[digit]] = arr[j];  
                count[digit]++;  
            }  
  
            // 将临时数组中的元素拷贝回原数组  
            int index = 0;  
            for (int k = 0; k < 10; k++) {  
                if (count[k] != 0) {  
                    for (int l = 0; l < count[k]; l++) {  
                        arr[index++] = temp[k][l];  
                    }  
                    count[k] = 0; // 重置计数  
                }  
            }  
        }  
    }  
  
    // 找到数组中的最大数  
    private static int findMax(int[] arr) {  
        int max = arr[0];  
        for (int i = 1; i < arr.length; i++) {  
            if (arr[i] > max) {  
                max = arr[i];  
            }  
        }  
        return max;  
    }  
  
    // 获取最大数的位数  
    private static int getMaxDigit(int num) {  
        int count = 0;  
        while (num != 0) {  
            num /= 10;  
            count++;  
        }  
        return count;  
    }  
  
    // 获取一个数的第i位(从最低位开始计数)  
    private static int getDigit(int num, int i) {  
        return (num / (int) Math.pow(10, i - 1)) % 10;  
    }  
}

标签:arr,八大,int,基础,num,static,排序,public
From: https://www.cnblogs.com/zjjtt/p/18218645

相关文章

  • Python基础篇(集成开发环境 PyCharm )
    PyCharm简介与下载PyCharm是由JetBrains打造的一款PythonIDE,是一款功能强大的Python编辑器,具有跨平台性,支持macOS、Windows、Linux系统。PyCharm具有:调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制等优点。PyCharm下载地址:......
  • html+CSS部分基础运用8
    1.P147实验1,完成页面制作效果。图7-1木兰花令效果图2.P147实验2,完成页面制作效果。项目1<!DOCTYPEhtml><htmllang="en"><head>  <metacharset="UTF-8">  <linktype="text/css">  <title>木兰花令</title>......
  • html+CSS部分基础运用7
    项目1 设计简易灯箱画廊1.实验所需素材在trees文件夹中提供一个MP3文件和18个JPG文件,设计页面时可以使用。2.编程实现简易灯箱画廊,鼠标单击任一个图像超链接,在底部浮动框架中显示大图像,效果如图4-1所示的页面。图4-1简易灯箱画廊项目2 设计支持音频、视频播放的......
  • linux基础知识
    一、连接工具(1)(推荐,免费)FinalShell  FinalShell SSH工具,服务器管理,远程桌面加速软件,支持Windows,macOS,Linux,版本4.3.10,更新日期2023.12.31 - FinalShell官网 (hostbuf.com)(2)XShell (有家庭和学校版)(更好用,但是公司不推荐)二、查看系统查看系统内核uname -aLinux......
  • 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了
    黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了这篇文章没有什么套路。就是一套自学理论和方向,具体的需要配合网络黑白去学习。毕竟是有网络才会有黑白!有自学也有培训!黑客进阶资源资料包1.打死也不要相信什么分分钟钟教你成为大黑阔的,各种包教包会的教程,就算......
  • Kyndryl 与 Nvidia 建立新的人工智能基础设施合作伙伴关系
    Kyndryl与Nvidia宣布达成新的人工智能基础设施战略合作,共同推动AI技术的广泛应用。根据这一合作,Nvidia的先进AI软件解决方案将被引入Kyndryl的开放集成平台——KyndrylBridge,以优化基础设施工作负载,并为客户提供更高效的IT服务。KyndrylBridge平台将针对运行Nvidia计算和软......
  • 持续性学习-Day16(前端基础JavaScript)
    LearnJavaScript参考教学视频:秦疆参考知识UI框架Ant-design:阿里巴巴出品,基于React的UI框架ElementUI、iview、ice:饿了吗出品,基于VUE的UI框架BootStrap:Twitter推出的一个用于前端开发的开源工具包AmazeUI:一款HTML5跨屏前端框架JavaScript构建工具Babel:JS编译......
  • Android NDK使用指南(基础篇)
    引言在Android开发中,大多数应用程序都是用Java或Kotlin编写的。然而,有时候我们需要使用C或C++代码来提高性能,或者为了与现有的C/C++库集成。AndroidNDK就是为此目的而设计的工具包。本文将介绍AndroidNDK的相关基本概念和基础使用方法,帮助读者初步理解NDK。......
  • 零基础成为黑客
    零基础成为黑客笔者刚乱入了CTF,算是入门了,此处分享一下入门经验一个漏洞练习平台:https://github.com/gh0stkey/DoraBox使用教程参考:https://www.cnblogs.com/zhaijiahui/p/10789251.html攻防世界:https://adworld.xctf.org.cn/task这个网站很良心,第一次点开这个网站,仿......
  • 数据结构的直接插入排序(C语言版)
    一.直接插入排序的基本概念1.直接插入排序的基本思想将数组分为已排序和未排序两部分。每次从未排序部分取出一个元素,将其插入到已排序部分的合适位置,使得已排序部分保持有序。重复步骤2,直到整个数组有序。2.排序的工作原理假设前i-1个元素已经有序,现在要将......