排序算法C#实现之选择排序详解

【任务目标】

将无序数组变为有序数组

【选择排序原理】

  • 先从数组中选出一个最小的元素,将其与数组首元素交换位置
  • 从剩下的n-1个元素中选出最小的元素,将其与数组的第二个元素交换位置
  • 从剩下的n-2个元素中选出最小的元素,将其与数组的第三个元素交换位置
  • 以此类推,直到剩下的元素个数为0

【选择排序原理概括】

通过循环,每次选出在当前的剩余元素中最小的元素,使得这些选出的元素构成有序数组

【代码实现】

using System;


namespace SelectionSort
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] A = new int[30];
            Random ra = new Random();
            for (int i = 0; i < 30; i++)
            {
                A[i] = ra.Next(200);
            }
            Program ps = new Program();
            ps.SelectSort(A);
            Console.WriteLine("排序结果:");
            foreach (int a in A)
            {
                Console.Write(a + " ");
            }
            bool isSorted = true;
            for (int i = 0; i < A.Length-1; i++)
            {
                if (A[i] > A[i + 1])
                {
                    isSorted = false;
                    break;
                }
            }
            Console.Write(isSorted);

            Console.ReadKey();
        }

        public void SelectSort(int[] A)
        {
            for (int i = 0; i < A.Length-1; i++)//在第n-1次就可以结束循环
            {
                int index = i;
                for (int j = i+1; j < A.Length; j++)
                {
                    if (A[index] > A[j])//找出最小元素的索引
                    {
                        index = j;
                    }
                }
                if (index != i)//交换位置
                {
                    int temp = A[i];
                    A[i] = A[index];
                    A[index] = temp;
                }
            }
        }

     
    }
}

【实现结果】

【考虑其他情况】

【元素已经有序或接近有序】例如,对A={0,1,2,3,4,5,6,7,8,9}和A={3,1,2,0,4,5,6,7,8,9},因为每次要选出最小的元素,所以不可避免地要将剩余的所有元素比较一次。选择排序在这种情况下,仍要较长的执行过程。

【元素完全逆序或混乱】例如,对A={9,8,7,6,5,4,3,2,1,0},同上,选出最小元素时不可避免地要将所有元素比较一次。坏的情况与好的情况都要较长的执行过程。

【有多个相同的元素】由于要交换位置,排序前后相同元素的相对次序会改变。

【选择排序改进】

按照选择排序的原理,我们也可以在每次选出最大的元素,将其放在数组的后端。进而,我们可以同时选出最小和最大的元素,分别放在数组的前端和后端。

(还有很多其他改进方向:怎么样更快选出最小的元素;怎么样使得排序前后相同元素的相对次序不改变等)

【改进代码实现】

        public void SelectSort2(int[] A)
        {
            for (int i = 0; i < A.Length >> 1; i++)//考虑了元素个数为偶数、奇数的情况
            {
                int MaxIndex = i;
                int MinIndex = i;
                for (int j = i; j < (A.Length - i); j++)//找到最小、最大元素的位置
                {
                    if (A[MinIndex] > A[j])
                    {
                        MinIndex = j;
                    }
                    if (A[MaxIndex] < A[j])
                    {
                        MaxIndex = j;
                    }
                }
                if (MaxIndex == i && MinIndex == A.Length - 1 - i)
                {//特殊位置:最大的在最前面,最小的在最后面
                    swap(ref A[MaxIndex], ref A[MinIndex]);
                }
                else if (MaxIndex == i)//特殊位置:最大的在最前面,最小的在后面
                {
                    swap(ref A[MaxIndex], ref A[A.Length - 1 - i]);
                    swap(ref A[MinIndex], ref A[i]);
                }
                else //(MinIndex == A.Length - 1 - i)特殊位置:最小的在最后面,最小的在前面
                     //和普通情况
                {
                    swap(ref A[MinIndex], ref A[i]);
                    swap(ref A[MaxIndex], ref A[A.Length - 1 - i]);
                }


            }
        }

        //注意交换时用ref参数
        public void swap(ref int a, ref int b)
        {
            int temp = a;
            a = b;
            b = temp;
        }

【改进结果】

【选择排序和冒泡排序的区别】

  • 冒泡排序将最大的元素逐渐后移,选择排序将最大的元素直接右移
  • 每次循环时,冒泡排序会将大的元素逐渐后移,选择排序只会将最大的元素直接右移
  • 排序后,冒泡排序不会改变相同元素的相对次序,选择排序会改变

【选择排序和插入排序的区别】

  • 选择排序的排序在查找(选择)最小的元素时完成,插入排序在插入任意的元素时完成
  • 排序后,插入排序不会改变相同元素的相对次序,选择排序会改变

【参考】

[1]邓俊辉.数据结构(C++语言版)第三版[M]

【相关链接】

排序算法C#实现之冒泡排序详解

排序算法C#实现之归并排序详解

排序算法C#实现之插入排序详解

你可能感兴趣的:(数据结构与算法,排序算法,选择排序,C#实现)