Java浅谈两种常用的排序

常用的排序方法有多种,这里只说说个人对选择排序和冒泡排序这两个最常用的排序方法的一些看法。

   首先,这里是按排序规则是按从小到大的顺序排序。然后,排序方法中接收的只有一个参数,即一个数组名。

最后,排序后并未将排序后的数组元素依次输出,故而返回值是void,至于输出操作,可另外自行定义。

   下面是具体的介绍。

   1.选择排序

       代码示例:

    for(inti=0;i<arr.length-1;i++){

       for(intj=i+1;j<arr.length;j++){

         if(arr[i]>arr[j]){

            swap(arr,i,j);

         }

       }

    }

        选择排序的思想是依次找到数组中的相对最小元素,并依次将其放于相应位置上。具体说来就是先找到最小元素,将其放于数组中第一个元素的位置,然后找到第二小元素,将其放于数组中第二个元素的位置。具体做法是让数组中第一个元素与后面所有元素进行比较,如果后面的元素比第一个元素小,则将它们位置互换,然后让当前第一个元素继续与后面的元素比较,也就是说,确保在已比较的元素中,当前第一个元素是最小的。

      这样的比较思想需要通过双层for循环才能完成。具体如下:

        外层循环:for(inti=0;i<arr.length-1;i++)

 外层循环控制比较元素的起始位置,即当起始位置为0时,要比较的是角标为0的元素和其后面的元素,依次类推。循环中之所以控制条件是i<arr.length-1而不是i<arr.length,是因为角标为arr.length-2的元素是数组中的倒数第二页元素,而与它进行比较的是角标为arr.length-1的元素,即最后一个元素。也就是说,此次比较是排序中的最后一次元素比较。另外,如果循环控制条件改为i<arr.length,由于内循环中有j=i+1语句,那么将此时j为arr.length,造成角标越界,产生错误。综上两种情况,循环控制条件为i<arr.length-1是最佳也是最合理的选择。

        内层循环: for(intj=i+1;j<arr.length;j++){

         if(arr[i]>arr[j]){

            swap(arr,i,j);

         }

       }
内存循环主要负责元素大小比较的具体操作,j=i+1语句决定了此层循环中与指定比较位置元素比较的元素开始位置,即此层循环中i的值不变。另外,互换位置操作是调用了一个函数swap进行实现的,这里不对swap进行另述,它的功能就是将指定数组中的指定位置的两个元素互换位置,而接收的参数中有数组名,这是必须的,因为它代表着引用地址,通过它操作对应的实际数组。
 

   2.冒泡排序

代码示例:

for(inti=0;i<arr.length-1;i++){

       for(intj=0;j<arr.length-i-1;j++){

         if(arr[j]>arr[j+1]){

            swap(arr,i,j);

         }

       }

  }

       冒泡排序的思想是将数组中的前一个元素a与后一个元素b进行比较,如果a>b,则将二者位置互换。否则不进行任何操作。

       具体是:第一个元素与第二元素比较,并进行相应操作。之后,第二个元素与第三个元素进行比较,并完成相应操作。。。依此方式完成所有元素的比较。要想在这种思想下把数组中所有元素比较完,需要双层for循环才能完成。

       外层循环:for(inti=0;i<arr.length-1;i++)

外层循环并没有什么特别的地方,可以看出,它是最常见的for循环形式。它控制着内层循环元素比较的轮数,其中循环控制条件是i<arr.length-1,也就是说外层循环的次数是数组元素个数减1,这是必然的,因为如果数组中只有两个元素,那么只需要一轮比较即可。

  内层循环:for(intj=0;j<arr.length-i-1;j++){

         if(arr[j]>arr[j+1]){

            swap(arr,i,j);

         }

       }

内层循环控制着要进行比较的元素的角标范围,而且要进行判断并作出相应操作。

冒泡排序的思想决定了排序过程结果是最大的先排到数组最末位置,然后次大的依次排其左边,这是针对内层循环每轮的操作结果而言的(这里要注意,在选择排序中,其排序思想决定了先排的是最小元素,且放到了数组首位置,这点正好与冒泡排序相反)。

内层循环的控制条件是i<arr.length-i-1,它控制着要比较的元素的角标值范围。这里要注意,j的初值不变,是0,范围是通过arr.length-i-1来确定,arr.length-i是随着外循环的i的值来改变要比较元素的范围,但是又减1,即arr.length-i-1是因为,每次比较,都是小角标元素与其右边相邻的大角标元素比较。外循环的第一轮循环时,所有元素进行比较,最后的一次比较是数组中倒数第二个元素与其右边元素,即倒数第一个元素比较。此时倒数第二个元素的角标是j=arr.length-i-2,而判断条件中的arr[j+1]正是倒数第一个元素。也就是说,如果j=arr.length-i-1时,将出现角标越界情况,导致出现错误,所以,控制条件设为j<arr.length-i-1,即j的最大值只能是j=arr.length-i-2。其实,j=arr.length-i-1时,它的右边已没有元素了,也不必进行比较了。综上两方面来看,将控制条件设为j<arr.length-i-1是最佳且是最合理的,这个原因跟选择排序中内循环控制条件的设置原因类似。

swap(arr,i,j)是调用的交换数组两元素位置的一个函数,这与上面选择排序中的用法一样,因为这里只是讨论排序,所以对swap函数不做过多论述。

选择排序和冒泡排序有着不同甚至某些地方相反的思想,但其中的循环控制条件的设定又有着相似的原理。其实,只要理解了其中一种排序方法,就不难理解另外一种了。

发布了22 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yeziyfx/article/details/32726049