数据结构和算法之排序四:冒泡排序

  我们在学习排序算法的时候或许很多人接触到的都是冒泡和选择这两种排序算法,其实真的可以说的是这两种算法确实是比较经典的排序方法,同时,在我的理解中,这两个排序具有惊奇的相似点。何为冒泡排序,如果我们在家煮过水都能知道,在水即将沸腾的时候会有一个又一个的水泡往上冒,这个现象其实和冒泡排序还是比较相似的,今天我们来讲一下这个冒泡。我们看下边的这幅图进行理解一下

  

   我们可以发现所谓的冒泡其实就是使用相邻的两个数据进行比较,然后交换数据,让你的第二个数据始终是两个数据中最大的数据,这样我们进行N-1次循环就会达到我们想要的效果。话不多说直接上代码:

public static void bubbleSort(int arr[]){
      //外层循环控制需要排序的次数
    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]){
                    int k = arr[i];
                    arr[i] = arr[j];
                    arr[j] = k;
                }
            }
    }

}

  在这里我们还是会发现一些细节的地方,比如在我的里层循环中为什么出现-1这样奇怪的数据,又是为什么我要-i这样做是为什么。首先我们可以看到在取出两个相邻数据进行比较的时候我们选取的是从零开始,然后在和它的后一个数据进行比较,那么我们可以想象,在最后一个数据,arr.length-1的时候,如果我们依然使用下一个数据arr.length会不会造成数组下标越界,所以这就是我们需要-2的原因。我们又是为什么会-i呢,我们想一下,我们在经历过i次排序之后,是不是默认为最后的i个数据已经是有序的了,那么我们还需要对其中的数据进行比较么,答案很明显是不需要,所以为了优化一下排序,我们-i。当然在这里探讨的问题是可不可以换一种写法,不用考虑这个数组下标越界的情况,答案是当然可以,代码如下:

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


}

  我们可以看到这段代码和上一段的区别就是从1开始,然后选取上一个数据和它进行比较,这样我们就可以完全避免数组下标越界的情况产生,如果还不理解可以画图思考一下。

posted @ 2017-11-30 23:28  GoNewLife  阅读(2123)  评论(0编辑  收藏  举报