• 八大排序之选择排序


    一、基本思想

       每次从待排记录中选出最小值放在有序记录的末尾。等每一个待排元素均被选出后,整个记录排序就完成了。

    二、实现步骤

         这里采用双向选择排序,每次从待排记录中选出最大值和最小值,最大值和待排记录的最后一位交换位置,最小值和待排记录的第一位交换位置。

      注意,交换位置分如下情况:

      1)最大值在最左边,最小值在最右边。直接将最大值最小值相互交换即可。

       

      2)最大值在最左边,最小值在中间。必须先将最大值与最后一位交换,再将最小值与第一位交换。否则会出错,不信就试试。

                 

      3)最大值在中间,最小值在中间。随意谁先交换都行。

               

      4)最小值在最右边,最大值在中间。必须先将最小值与第一位交换,再将最大值与最后一位交换。

                  

      5)最小值在最右边,最大值在最左边。不用交换。

           

      

       对于上述5种情况,其实可以简化成如下情况来做。

      一、如果max在最左边,

            如果min在最右边,两者直接交换

            否则,先交换max,再交换min

      二、其他情况一律先交换min,再交换max。

      max在最左,min在最右这种情况,由于两次交换,等同于没交换,所以不会出现错误。

    三、实现代码

    测试工具类 点击这里

    package sort;
    
    import sort.util.*;
    
    /*
        选择排序思路:
        选择待排记录中最小值,放在左边
        双向选择,一次遍历中选出最大值放在右边,选出最小值放在左边
        
        时间复杂度:O(n2)
        空间复杂度:O(1)
        稳定性:    稳定
    */
    public class SelectSort implements ISort{
        
        public void sort(int[] a) {
            int n = a.length;
            for(int i = 0; i < n / 2; i++) {
                int maxId = i;
                int minId = i;
                for(int j = i; j <= n - i - 1; j++) {
                    if(a[j] > a[maxId]) {maxId = j;}
                    if(a[j] < a[minId]) {minId = j;}
                }
                                                                         //根据maxId的位置走不同的交换顺序
                int t = 0;
                if(maxId == i){
                    if(minId == n - 1 - i) {
                        t = a[maxId]; a[maxId] = a[minId]; a[minId] = t; //max和min位于相反的位置上,直接将其交换
                    }else{                                               
                        t = a[maxId]; a[maxId] = a[n-1-i]; a[n-1-i] = t; //max位于最左,先交换max
                        t = a[minId]; a[minId] = a[i];     a[i] = t;     //再交换min
                    }                
                }else{                                                  
                    t = a[minId]; a[minId] = a[i];     a[i] = t;         //min位于最右和其他情况,先交换min
                    t = a[maxId]; a[maxId] = a[n-1-i]; a[n-1-i] = t;
                }
            }
        }
        
        
        public static void main(String[] args) {
            int[] array = RandomArrayGenerator.getRandomArray(100 , 30);
            SortTestHelper.test(new SelectSort() , array);
        }
    }

    测试结果:

    四、总结分析

      时间复杂度:O(n2)

      空间复杂度:O(1)

      选择排序是一种比较直观易懂的排序算法,时间复杂度不理想,但几乎不占空间。下篇将展示选择排序的改进算法 ----- 堆排序。

  • 相关阅读:
    lua的数组下标是从1开始的
    DestroyImmediate的一些坑
    c#的IDisposable
    unity工具开发(转)
    winform控件命名规范对照表
    C#调用Exe程序示例
    System.Diagnostics.Process.Start的妙用
    C#中AppDomain.CurrentDomain.BaseDirectory及各种路径获取方法
    C# WindowsAPI
    TabPage判断重复添加Page
  • 原文地址:https://www.cnblogs.com/wanghang-learning/p/9202899.html
Copyright © 2020-2023  润新知