选择排序及改进

选择排序

基本思想

冒泡排序中有一个缺点,比如,我们比较第一个数a1与第二个数a2的时候,只要a1比a2大就会交换位置,但是我们并不能确定a2是最小的元素,假如后面还有比它更小的,该元素还会与a2再次进行交换,而且这种交换有可能发生多次才能确定a2的最终位置。

选择排序可以避免这种耗费时间的交换操作,从第一个元素开始,扫描整个待排数组,找到最小的元素放之后再与第一个元素交换位置,然后再从第二个元素开始,继续寻找最小的元素与第二个元素交换位置,依次类推。

java实现

[java] view plain copy print?

  1. //选择排序
  2. public void selectionSort(){
  3. int minPoint;  //存储最小元素的小标
  4. int len = array.length;
  5. int temp;
  6. int counter = 1;
  7. for(int i=0;i<len-1;i++){
  8. minPoint= i;
  9. for(int j=i+1;j<=len-1;j++){  //每完成一轮排序,就确定了一个相对最小元素,下一轮排序只对后面的元素排序
  10. if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
  11. minPoint= j;
  12. }
  13. }
  14. if(minPoint!=i){  //如果发现了更小的元素,交换位置
  15. temp= array[i];
  16. array[i]= array[minPoint];
  17. array[minPoint]= temp;
  18. }
  19. System.out.print("第"+counter+"轮排序结果:");
  20. display();
  21. counter++;
  22. }
  23. }

//选择排序
   public void selectionSort(){
       int minPoint;  //存储最小元素的小标
       int len = array.length;
       int temp;
       int counter = 1;

       for(int i=0;i<len-1;i++){

          minPoint= i;
          for(int j=i+1;j<=len-1;j++){  //每完成一轮排序,就确定了一个相对最小元素,下一轮排序只对后面的元素排序
              if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
                 minPoint= j;
              }
          }

          if(minPoint!=i){  //如果发现了更小的元素,交换位置
              temp= array[i];
              array[i]= array[minPoint];
              array[minPoint]= temp;
          }

          System.out.print("第"+counter+"轮排序结果:");
          display();
          counter++;
       }
   }

算法分析

选择排序与冒泡排序一样,需要进行N*(N-1)/2次比较,但是只需要N次交换,当N很大时,交换次数的时间影响力更大,所以选择排序的时间复杂度为O(N2)

虽然选择排序与冒泡排序在时间复杂度属于同一量级,但是毫无疑问选择排序的效率更高,因为它的交换操作次数更少,而且在交换操作比比较操作的时间级大得多时,选择排序的速度是相当快的。

选择排序的改进

传统的选择排序每次只确定最小值,根据改进冒泡算法的经验,我们可以对排序算法进行如下改进:每趟排序确定两个最值——最大值与最小值,这样就可以将排序趟数缩减一半。

改进后的代码如下:

[java] view plain copy print?

  1. //选择排序改进版
  2. public void selectionSort_improvement(){
  3. int minPoint;  //存储最小元素的小标
  4. int maxPoint;  //存储最大元素的小标
  5. int len = array.length;
  6. int temp;
  7. int counter = 1;
  8. for(int i=0;i<len/2;i++){
  9. minPoint= i;
  10. maxPoint= i;
  11. for(int j=i+1;j<=len-1-i;j++){  //每完成一轮排序,就确定了两个最值,下一轮排序时比较范围减少两个元素
  12. if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
  13. minPoint= j;
  14. continue;
  15. }else if(array[j]>array[maxPoint]){  //如果待排数组中的某个元素比当前元素大,maxPoint指向该元素的下标
  16. maxPoint= j;
  17. }
  18. }
  19. if(minPoint!=i){  //如果发现了更小的元素,与第一个元素交换位置
  20. temp= array[i];
  21. array[i]= array[minPoint];
  22. array[minPoint]= temp;
  23. //原来的第一个元素已经与下标为minPoint的元素交换了位置
  24. //如果之前maxPoint指向的是第一个元素,那么需要将maxPoint重新指向array[minPoint]
  25. //因为现在array[minPoint]存放的才是之前第一个元素中的数据
  26. if(maxPoint== i){
  27. maxPoint= minPoint;
  28. }
  29. }
  30. if(maxPoint!=len-1-i){  //如果发现了更大的元素,与最后一个元素交换位置
  31. temp= array[len-1-i];
  32. array[len-1-i]= array[maxPoint];
  33. array[maxPoint]= temp;
  34. }
  35. System.out.print("第"+counter+"轮排序结果:");
  36. display();
  37. counter++;
  38. }
  39. }

//选择排序改进版
   public void selectionSort_improvement(){
       int minPoint;  //存储最小元素的小标
       int maxPoint;  //存储最大元素的小标
       int len = array.length;
       int temp;
       int counter = 1;

       for(int i=0;i<len/2;i++){

          minPoint= i;
          maxPoint= i;
          for(int j=i+1;j<=len-1-i;j++){  //每完成一轮排序,就确定了两个最值,下一轮排序时比较范围减少两个元素
              if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
                 minPoint= j;
                 continue;
              }else if(array[j]>array[maxPoint]){  //如果待排数组中的某个元素比当前元素大,maxPoint指向该元素的下标
                 maxPoint= j;
              }
          }

          if(minPoint!=i){  //如果发现了更小的元素,与第一个元素交换位置
              temp= array[i];
              array[i]= array[minPoint];
              array[minPoint]= temp;

              //原来的第一个元素已经与下标为minPoint的元素交换了位置
              //如果之前maxPoint指向的是第一个元素,那么需要将maxPoint重新指向array[minPoint]
              //因为现在array[minPoint]存放的才是之前第一个元素中的数据
              if(maxPoint== i){
                 maxPoint= minPoint;
              }

          }

          if(maxPoint!=len-1-i){  //如果发现了更大的元素,与最后一个元素交换位置
              temp= array[len-1-i];
              array[len-1-i]= array[maxPoint];
              array[maxPoint]= temp;
          }

          System.out.print("第"+counter+"轮排序结果:");
          display();
          counter++;
       }
   }
时间: 2024-10-27 06:06:27

选择排序及改进的相关文章

排序算法(二)——选择排序及改进

选择排序 基本思想 冒泡排序中有一个缺点,比如,我们比较第一个数a1与第二个数a2的时候,只要a1比a2大就会交换位置,但是我们并不能确定a2是最小的元素,假如后面还有比它更小的,该元素还会与a2再次进行交换,而且这种交换有可能发生多次才能确定a2的最终位置. 选择排序可以避免这种耗费时间的交换操作,从第一个元素开始,扫描整个待排数组,找到最小的元素放之后再与第一个元素交换位置,然后再从第二个元素开始,继续寻找最小的元素与第二个元素交换位置,依次类推. java实现 //选择排序 public

排序系列 之 简单选择排序及其改进算法 —— Java实现

简单选择排序算法: 基本思想: 在待排序数据中,选出最小的一个数与第一个位置的数交换:然后在剩下的数中选出最小的数与第二个数交换:依次类推,直至循环到只剩下两个数进行比较为止. 实例: 0.初始状态 3,1,5,7,2,4,9,6(共8个数) 1.n=8 个数中,最小数值为1,与第一个数交换:1,3,5,7,2,4,9,6 2.剩下 n-1=7 个数中,最小数值为2,与第二个数交换:1,2,5,7,3,4,9,6 3.剩下 n-2=6 个数中,最小数值为3,与第三个数交换:1,2,3,7,5,4

经典排序算法--简单选择排序

算法简介 简单选择排序是一种选择排序. 选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止. 白话理解 依然已排队为例,在排队时,有的老师可能会选择这样排序,先在一列中选出最矮的,放在第一位,然后选出第二矮的,放在第二位.队伍完成排序.而这就是选择排序的思想. 简单排序处理流程 (1)从待排序序列中,找到关键字最小的元素: (2)如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换: (3)从余下的 N - 1 个元素中,找出关键字最小

选择排序—简单选择排序(Simple Selection Sort)

基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 简单选择排序的示例: 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推..... 第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与

选择排序—简单选择排序(Simple Selection Sort)原理以及Java实现

基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 简单选择排序的示例: 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推..... 第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与

算法之简单选择排序和堆排序

3. 选择排序-简单选择排序(Simple Selection Sort) 基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 简单选择排序的示例: 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推.....

选择排序--------简单选择排序

基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推..... 第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与第i 个记录交换, 直

排序之选择排序、堆排序、归并排序、高速排序

本学习笔记内容部分来自网易云课堂浙江大学数据结构视频,及海子的博客:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html以及~大器晚成~的博客http://www.cnblogs.com/luchen927/archive/2012/02/29/2368070.html 1.选择排序 基本思想:在一个长度为N的无序数组中.在第一趟遍历N个数据,找出当中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出当中

OJ刷题之《二元选择排序》

Description 注:本题只需要提交标记为修改部分之间的代码,请按照C++语言方式提交. 二元选择排序:对传统的选择排序算法改进,在一趟比较过程中,同时记录最大值和最小值位置,将最小值与第一个元素交换,最大值与最后一个元素交换,即一趟比较确定两个元素,对剩下的序列重复上述过程,直至序列为空. #include<iostream> using namespace std; int main() { int a[100],i,n; cin>>n; for(i=0; i<n;