首页 > 编程语言 >java数组之冒泡排序、快速排序

java数组之冒泡排序、快速排序

时间:2024-07-13 22:28:45浏览次数:25  
标签:arr java int 冒泡排序 high 算法 排序 data

一、排序算法概述

1.算法定义

  • 排序:假设含有n个记录的序列为{R1,R2,...,Rn},其相应的关键字序列为{K1,K2,...,Kn}。将这些记录重新排序为{Ri1,Ri2,...,Rin},使得相应的关键字值满足条Ki1<=Ki2<=...<=Kin,这样的一种操作称为排序。

  • 通常来说,排序的目的是快速查找。

2.衡量排序算法的优劣

  • 时间复杂度:分析关键字的比较次数和记录的移动次数
  • 常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n<sup>2</sup>)<Ο(n<sup>3</sup>)<…<Ο(2<sup>n</sup>)<Ο(n!)<O(n<sup>n</sup>)
  • 空间复杂度:分析排序算法中需要多少辅助内存。

一个算法程序完全执行的时间容易受当前电脑的配置和当前运行的其他程序的影响,所以只使用程序执行时间来评价一个算法的优劣是不靠谱的。

一个算法的空间复杂度S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。

  • 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。

 3.排序算法分类

  • 排序算法分类:内部排序和外部排序

    • 内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。

    • 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。

4.十大内部排序算法

数组的排序算法很多,实现方式各不相同,时间复杂度、空间复杂度、稳定性也各不相同:

常见时间复杂度所消耗的时间从小到大排序:

 O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

 二、冒泡排序

a) 排序思想

  1. 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。

  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

  3. 针对所有的元素重复以上的步骤,除了最后一个。

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较为止。

b)动态演示:

排序(冒泡排序,选择排序,插入排序,归并排序,快速排序,计数排序,基数排序) - VisuAlgo排序算法将一串数组(一个列表)中的元素(整数,数字,字符串等)按某种顺序(增大,减小,字典顺序等)重新排列。有很多种不同的排序算法,每一种都有各自的优势和限制。排序常常作为计算机课程中的介绍性问题,用以介绍一系列的算法思路。不失普遍性,我们在此可视化中,只将(可能包含重复)的整数数组排序至非减。试试点击 Bubble Sort 来可视化五个(含重复项)的杂乱整数的排序。icon-default.png?t=N7T8https://visualgo.net/zh/sorting

c)代码实现

代码实现一

public class Test19BubbleSort{
    public static void main(String[] args){
        int[] arr = {6,9,2,9,1};

        //目标:从小到大
        //冒泡排序的轮数 = 元素的总个数 - 1
        //轮数是多轮,每一轮比较的次数是多次,需要用到双重循环,即循环嵌套
        //外循环控制 轮数,内循环控制每一轮的比较次数和过程
        for(int i=1; i<arr.length; i++){ //循环次数是arr.length-1次/轮
            for(int j=0; j<arr.length-i; j++){
                //希望的是arr[j] < arr[j+1]
                if(arr[j] > arr[j+1]){
                    //交换arr[j]与arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

        //完成排序,遍历结果
        for(int i=0; i<arr.length; i++){
            System.out.print(arr[i]+"  ");
        }
    }
}

代码实现二(优化)

class Test19BubbleSort2{
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};

        //从小到大排序
        for (int i = 0; i < arr.length - 1; i++) {
            boolean flag = true;//假设数组已经是有序的
            for (int j = 0; j < arr.length - 1 - i; j++) {
                //希望的是arr[j] < arr[j+1]
                if (arr[j] > arr[j + 1]) {
                    //交换arr[j]与arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;

                    flag = false;//如果元素发生了交换,那么说明数组还没有排好序
                }
            }
            if (flag) {
                break;
            }
        }

        //完成排序,遍历结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "  ");
        }
    }
}

三、快速排序

1.快排简述

快速排序(Quick Sort)由图灵奖获得者Tony Hoare发明,被列为20世纪十大算法之一,是迄今为止所有内排序算法中速度最快的一种,快速排序的时间复杂度为O(nlog(n))。

快速排序通常明显比同为O(nlogn)的其他算法更快,因此常被采用,而且快排采用了分治法的思想,所以在很多笔试面试中能经常看到快排的影子。

2.排序思想

a)从数列中挑出一个元素,称为"基准"(pivot),
b)重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
c)递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
d)递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

3.动态演示

https://visualgo.net/zh/sortingicon-default.png?t=N7T8https://visualgo.net/zh/sorting

 4.图示解说

a)第一轮

b)第二轮

 

5)内部排序的性能比较与选择

  • 性能比较

    • 从平均时间而言:快速排序最佳。但在最坏情况下时间性能不如堆排序和归并排序。

    • 从算法简单性看:由于直接选择排序、直接插入排序和冒泡排序的算法比较简单,将其认为是简单算法。对于Shell排序、堆排序、快速排序和归并排序算法,其算法比较复杂,认为是复杂排序。

    • 从稳定性看:直接插入排序、冒泡排序和归并排序时稳定的;而直接选择排序、快速排序、 Shell排序和堆排序是不稳定排序

    • 从待排序的记录数n的大小看,n较小时,宜采用简单排序;而n较大时宜采用改进排序。

  • 选择

    • 若n较小(如n≤50),可采用直接插入或直接选择排序。 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。

    • 若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜;

    • 若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。

5.代码实现

public class QuickSort {
    public static void main(String[] args) {
        int[] data = {9, -16, 30, 23, -30, -49, 25, 21, 30};
        System.out.println("排序之前:");
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }

        quickSort(data);//调用实现快排的方法

        System.out.println("\n排序之后:");
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }

    public static void quickSort(int[] data) {
        subSort(data, 0, data.length - 1);
    }

    private static void subSort(int[] data, int start, int end) {
        if (start < end) {
            int base = data[start];
            int low = start;
            int high = end + 1;
            while (true) {
                while (low < end && data[++low] - base <= 0)
                    ;
                while (high > start && data[--high] - base >= 0)
                    ;
                if (low < high) {
                    //交换data数组[low]与[high]位置的元素
                    swap(data, low, high);
                } else {
                    break;
                }
            }
            //交换data数组[start]与[high]位置的元素
            swap(data, start, high);

            //经过代码[start, high)部分的元素 比[high, end]都小

            //通过递归调用,对data数组[start, high-1]部分的元素重复刚才的过程
            subSort(data, start, high - 1);
            //通过递归调用,对data数组[high+1,end]部分的元素重复刚才的过程
            subSort(data, high + 1, end);
        }
    }

    private static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

标签:arr,java,int,冒泡排序,high,算法,排序,data
From: https://blog.csdn.net/weixin_44554794/article/details/140361078

相关文章

  • 希尔排序--插入排序升级版
    #include<stdio.h>//希尔排序函数voidshellSort(intarr[],intsize){inti,j,gap,temp;//计算初始增量gap=1;while(gap<size){gap=gap*3+1;//Knuth增量序列for(i=gap;i<size;i++){//当前待插......
  • 使用Java开发一个简易健康计算器
            开发一个简单的健康计算器应用程序,它可以接收用户的输入(如年龄、性别、身高、体重),并计算出用户的BMI(身体质量指数)和基础代谢率(BMR)。    一、BMI(BodyMassIndex,身体质量指数)是用来评估体重是否适宜的一个常用指标。它通过体重(以千克为单位)除以身......
  • IO输入输出流例子:Java对象输出json文本:
    读取文件:原始字节输入流(低级):publicclassCharCacheIOReader{publicstaticvoidmain(String[]args){try(//原始字节输入流(低级)Readerfr=newFileReader("src\\OutputStream.txt");//创建一个字......
  • 每周JAVA学习汇总
    本周我自学了Java的输入与输出包括了:使用Scanner类进行输入导入Scanner类:importjava.util.Scanner;创建Scanner对象:Scannerscanner=newScanner(System.in);读取不同类型的数据:读取字符串:StringinputString=scanner.nextLine();读取整数:intinputInt=scanner.ne......
  • 自学Java第二周
    本周学习一、Java能干些什么?1.共三个版本:JavaSE、JavaEE、JavaMEJavaSE:Java语言的(标准版),用于桌面应用开发,是其他两个版本的基础。JavaME:Java语言的(小型版),用于嵌入式电子设备或者小型移动设备。JavaEE:Java语言的(企业版),用于Web方向的网站开发(浏览器和服务器)。在这......
  • Java学习第二周
    标识符是用来给变量,类,方法以及包进行命名的。标识符的命名规则1.必须以字母、下划线“”、美元符“$”开头。2.其他部分可以是字母、下划线“”、美元符“$”和数字的人员组合·。3.大小写敏感,且长度无限制。4.不可以是Java的关键字。标识符使用规范表示类名的标识符:每个单......
  • java 基本语法1
    1.安装idea,java编译器,编译器会自动对代码进行编译,然后运行得到结果.idea分为社区版(免费),企业版(收费),https://www.jetbrains.com/zh-cn/idea/download/?section=windows从官网下载对应版本安装即可.2.java的数据类型有四类八项.整数,小数,字符,布尔.其中整数:intlongbyt......
  • java1
    1.安装一个Java开发环境,我安装的是JDK(从b站上学习的安装教程以及如何配置环境变量等等);同时我也对此进行了初步的了解JDK即Java开发工具包。它是用于构建在Java平台上发布的应用程序、Applet和组件的开发环境。JDK包含了Java编译器、Java文档生成工具、Java打包工具等,是整个Java......
  • [Java IO] 流原理及流的分类
    JavaIO流概念JavaIO(输入/输出)流是Java用于处理输入和输出操作的一种方式。JavaIO系统主要基于流(Stream)的概念,流是一组有序的数据序列,可以是输入流(从数据源读取数据)或输出流(向数据目标写入数据)。JavaIO流分类按操作数据单位不同分为:字节流(8bit)如二进制文件;字符流......
  • 从零学习的JAVAday8~day14
    在安装eclipse时我们直接打开eclipse官网我们点击下载并安装到合适的位置即可。打开eclipse后我们就可以创建Java文件了然后再创建一个Java类,这样我们就可以在里面写我们第一个java代码了这就是我们的第一个代码,意思为输出“helloworld”。我们可以看到运行代码后输出了“he......