java排序算法(4)—冒泡排序

1、概述

排序就是将一组对象按照某种逻辑顺序重新排列的过程。

冒泡排序是依次比较相邻的两个数,将小数放在前面,大数放在后面。

  • 冒泡排序基本思想:

(1)第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。

(2)重复第一趟步骤,直至全部排序完成。

2、代码实现

package com.chunsoft.sort;

public class BubbleSort {
    public static void main(String[] args) {
        int data[] = {9,8,7,6,5,4,3,2,8}; 
        F_BubbleSort(data);
        for(int num :data) {
            System.out.println(num);
        }  
    }
    //排序方法
    public static void F_BubbleSort(int[] data) {
        int n = data.length; //输入数据长度
        int temp = 0;   //辅助元素
        //边界验证
        if(data == null ||  n <= 0) {
            return;
        }
        //n个数字需要n-1躺排序
        for(int i = 0;i < n-1;i ++) {
            //比较次数为n-1-i(趟数),因为每趟比较好后,确定一个元素位置
            for(int j = 0;j < n-1-i;j ++) {
                //如果左边元素比右边大,则交换位置,最终找到这一趟的最大值
                if(data[j] > data[j+1]) {
                    temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                }
            }
        }
    }
}

由代码可知,N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数。

改进:
有种情况,当元素已经完全有序时,但循环仍然继续,这方面可以稍微改进下,即内层循环判断有序后,便不再循环,在一定程度上提高了效率:

//排序方法
    public static void F_BubbleSort(int[] data) {
        int n = data.length; //输入数据长度
        int temp = 0;   //辅助元素
        boolean flag = true;
        //边界验证
        if(data == null ||  n <= 0) {
            return;
        }
        //n个数字需要n-1躺排序
        for(int i = 0;i < n-1 && flag;i ++) {
            //比较次数为n-1-i(趟数),因为每趟比较好后,确定一个元素位置
            flag = false;
            for(int j = 0;j < n-1-i;j ++) {
                //如果左边元素比右边大,则交换位置,最终找到这一趟的最大值
                if(data[j] > data[j+1]) {
                    temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                    flag = ture;
                }
            }
        }
    }

3、复杂度和稳定性

(1)复杂度

  • 如果数据是正序,则一趟就可以完成排序,所需的比较次数和记录移动次数均是最小值,即比较次数:n-1,移动次数:0;
  • 如果是反序,则需要n-1趟排序,每趟排序要进行n-i次比较,且每次比较必须移动记录三次来达到记录交换位置,比较次数:n*(n-1)/2,移动次数:3*n(n-1)/2
    时间复杂度:最好时间复杂度O(n)、平均复杂度和最坏时间复杂度O(N*N)
    空间复杂度:O(1)

(2)稳定性

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

稳定的:
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

(3)特点

每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值。第一趟比较之后,排在最后的一个数一定是最大的一个数,第二趟排序的时候,只需要比较除了最后一个数以外的其他的数,同样也能找出一个最大的数排在参与第二趟比较的数后面,第三趟比较的时候,只需要比较除了最后两个数以外的其他的数,以此类推……也就是说,每进行一趟比较,则每一趟少比较一次,一定程度上减少了算法的量。

你可能感兴趣的:(算法研究,java,冒泡排序,排序算法,复杂度,稳定性)