数据结构与算法-排序算法1-冒泡排序

发布于:2024-05-17 ⋅ 阅读:(146) ⋅ 点赞:(0)

本文先介绍排序算法,然后具体写冒泡排序。

目录

1.排序算法简介

2.常见的排序算法分类如下图:

3.冒泡排序:

1.介绍:

2.动态图解

3.举例

4.小结冒泡排序规则

5.冒泡排序代码

6.优化

7.优化后时间

代码:

运行结果:


1.排序算法简介

排序也称为排序算法。排序是将一组数据依据指定的顺序进行排列的过程。

分类:

  1. 内部排序:将需要处理的所有数据都加载到内存中进行排序。
  2. 外部排序:数据量过大(比如10亿个数据),无法全部加载到内存中,就需要借助外部存储(文件、磁盘等)进行排序。先加载一部分,排序完之后再加载另外一部分进行排序,排序完再合并。

2.常见的排序算法分类如下图:

稳定性口诀:

选泡插,快归堆希桶计基,不稳稳稳不稳稳,不稳不稳稳稳稳

3.冒泡排序:

1.介绍:

数组中n个元素,从数组第一个元素开始到最后一个元素,依次比较相邻元素的值,如果如果左端元素大于右端元素就交换它们的位置,使得较大的元素在右边。这样数组最右端的元素就是数组中的最大元素。一轮之后就找到了n个元素中的最大元素,浮到整个数组最后一个位置。接着对左边n-1个元素也这样交换,找到这n-1个元素中的最大值,浮到整个数组的倒数第二个位置。依此类推。直到整个数组有序排列。

冒泡排序就是用相邻交换的方式把大的元素换到右边。

2.动态图解

3.举例

比如原始数组为:3,9,-1,10,20

第一趟排序:

(1)3,9,-1,10,20将3和9比较,不用交换

(2)3,-1,9,10,20将9和-1比较,要交换

(3)3,-1,9,10,20将9和10比较,不用交换

(4)3,-1,9,10,20将10和20比较,不用交换

第二趟排序:

(1)-1,3,9,10,20将3和-1比较,要交换

(2)-1,3,9,10,20将3和9比较,不用交换

(3)-1,3,9,1020将9和10比较,不用交换

第三趟排序:

(1)-1,3,9,1020将-1和3比较,不用交换

(2)-1,3,9,10,20将3和9比较,不用交换

第四趟排序:

(1)-1,3,9,10,20将-1和3比较,不用交换

由于5个数据中四个数据已经确定顺序,所以不需要第五趟排序。

4.小结冒泡排序规则

①数组元素个数为n,就一共进行n-1次大循环

②每一趟排序的次数逐渐减少

③如果我们发现在某趟排序中没有发生一次交换,可以提前结束冒泡排序,也就是冒泡排序的优化。

5.冒泡排序代码

package com.xjj.sort;

import java.util.Arrays;

public class BubbleSort {
    public static void main(String[] args) {
        int arr[]={3,9,-1,10,20};
        BubbleSort(arr);
    }
    //为了例子写的原始写法,用于找规律
    public static void BubbleSort1(int []arr){
        int temp=0;
        //第一趟排序
        for(int j=0;j<arr.length-1;j++){
            if(arr[j]>arr[j+1]){
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
        System.out.println("第1趟排序后的结果:"+Arrays.toString(arr));
        //第二趟排序
        for(int j=0;j<arr.length-1-1;j++){
            if(arr[j]>arr[j+1]){
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
        System.out.println("第2趟排序后的结果:"+Arrays.toString(arr));
        //第3趟排序
        for(int j=0;j<arr.length-1-2;j++){
            if(arr[j]>arr[j+1]){
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
        System.out.println("第3趟排序后的结果:"+Arrays.toString(arr));
        //第4趟排序
        for(int j=0;j<arr.length-1-3;j++){
            if(arr[j]>arr[j+1]){
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
        System.out.println("第4趟排序后的结果:"+Arrays.toString(arr));
    }
    //由于上面的一段代码在重复,只有可以arr.length-1后面减去的数字不同,正好是i,用for循环包括起来
    //于是有了冒泡排序的代码
    public static void BubbleSort(int []arr){
        int temp=0;
        for(int i=0;i<arr.length-1;i++){
            for(int j=0;j<arr.length-1-i;j++){
                if(arr[j]>arr[j+1]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
            System.out.println("第"+(i+1)+"趟排序后的结果"+ Arrays.toString(arr));
        }
    }
    //达到效果的另一种写法
    public static void BubbleSort3(int []arr){
        int temp=0;
        for(int i=arr.length-1;i>0;i--){
            for(int j=0;j<i;j++){
                if(arr[j]>arr[j+1]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
            System.out.println("第"+(arr.length-i)+"趟排序后的结果"+ Arrays.toString(arr));
        }
    }
}

运行结果:

6.优化

因为在排序过程中,各个元素不断接近自己的位置,如果一趟比较下来没有进行过交换,那么说明这个序列是有序的。既然有序那后面还需要在一轮一轮比较吗?不需要吧。所以我们可以在排序过程中设置一个标注flag判断元素是否进行过交换,减少不必要的比较。

优化后代码:

package com.xjj.sort;
import java.util.Arrays;
public class BubbleSort {
    public static void main(String[] args) {
        int arr[]={3,9,-1,10,20};
        BubbleSort4(arr);
    }
    //用于优化冒泡排序代码
    public static void BubbleSort4(int []arr){
        int temp=0;
        boolean flag=false;//标识变量,表示是否进行过交换
        for(int i=0;i<arr.length-1;i++){
            for(int j=0;j<arr.length-1-i;j++){
                if(arr[j]>arr[j+1]){
                    flag=true;
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
            System.out.println("第"+(i+1)+"趟排序后的结果"+ Arrays.toString(arr));
            if(!flag){//也就是flag为false,在一趟排序中一次交换都没有发生
                break;
            }
            else{
                flag=false;//重置flag进行下一次判断,不然flag还是true的话到!flag时就是直接false,不会break了
            }
        }
    }
}

运行结果:

可以看到优化后,排序趟数减少了

再使得数组中原本就有序:1,2,3,4,5

运行结果:

一趟就可以,是不是感觉效率高多了!

7.优化后时间

插入段记录时间的代码。排序前记一次时间,排序后记一次时间。

然后输出元素的代码就先注释掉。

代码:

package com.xjj.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class BubbleSort {
    public static void main(String[] args) {
        int arr[]={3,9,-1,10,20};
        BubbleSort4(arr);
        //测试时间
        int[] arr2=new int[80000];
        for(int i=0;i<80000;i++){
            arr2[i]=(int)(Math.random()*80000);//生成一个【0,80000】之间的随机数
        }
        Date date1=new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str=simpleDateFormat.format(date1);
        System.out.println("排序前的时间为:"+date1Str);
        BubbleSort4(arr2);
        Date date2=new Date();
        String date2Str=simpleDateFormat.format(date2);
        System.out.println("排序后的时间为:"+date2Str);
    }
    //用于优化冒泡排序代码
    public static void BubbleSort4(int []arr){
        int temp=0;
        boolean flag=false;//标识变量,表示是否进行过交换
        for(int i=0;i<arr.length-1;i++){
            for(int j=0;j<arr.length-1-i;j++){
                if(arr[j]>arr[j+1]){
                    flag=true;
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
//            System.out.println("第"+(i+1)+"趟排序后的结果"+ Arrays.toString(arr));
            if(!flag){//也就是flag为false,在一趟排序中一次交换都没有发生
                break;
            }
            else{
                flag=false;//重置flag进行下一次判断,不然flag还是true的话到!flag时就是直接false,不会break了
            }
        }
    }
}

运行结果:

80000个元素,优化后的冒泡排序运行时间8秒。


后面会继续写选择排序、插入排序等排序算法的内容。分类排序部分写完之后再给出一些题目练习^_^加油加油