算法 冒泡排序,选择排序,插入排序


public static void maopao(int[] arrry) { //输出原数组 string strArray = string.Join(',', arrry); Console.WriteLine("排序之前:" + strArray); int temp = 0; //要排序的次数 for (int i = 0; i < arrry.Length - 1; i++) { //每次排序要交换位置的次数,因为每次冒泡一个最大的上去,所以下一次只需要arrry.Length - 1 - i次交换位置 for (int j = 0; j < arrry.Length - 1 - i; j++) { if (arrry[j] > arrry[j + 1]) { temp = arrry[j + 1]; arrry[j + 1] = arrry[j]; arrry[j] = temp; } } } strArray = string.Join(',', arrry); Console.WriteLine("排序之后:" + strArray); } }

冒泡排序就是,先比较a[0]和a[1],如果a[0]>a[1],交换两个位置的值,将较大的数放在1的位置,再比较a[1]和a[2],以此类推,这样第一轮(即外层循环第一次)过后,最大的数放到了数组的最后,经过数组长度-1次循环后,获得升序数组

 

       /// <summary>
        /// 选择排序,每次把最小的放到有序的后一位,可以说跟冒泡是相反的思路
        /// </summary>
        /// <param name="array"></param>
        public static void xuanze(int[] array)
        {
            Console.WriteLine("原数组:" + string.Join(',', array));
            int temp = 0;
            //通过不停地交换,最后一位肯定是最大,不需要再判断它,因此 i < array.Length - 1
            for (var i = 0; i < array.Length - 1; i++)
            {
                //记录当前无序部分最小的值的下标,默认是无序部分的起始下标
                int minIndex = i;
                //j = i + 1 是因为 minIndex=i,minIndex不需要跟自己比,而是跟下一位比
                for (var j = i + 1; j < array.Length; j++)
                {
                    //循环比较相邻的两个,拿到最小的下标
                    if (array[j] < array[minIndex])
                    {
                        minIndex = j;
                    }
                }
                //当默认最小i跟实际最小minIndex不相等时才交换,其实有没有无所谓,对时间复杂度几乎没有影响
                //交换剩余最小的值和无序部分起始下标的值
                if (minIndex != i)
                {
                    temp = array[minIndex];
                    array[minIndex] = array[i];
                    array[i] = temp;
                }
                Console.WriteLine(string.Join(',', array));
            }
        }

选择排序跟冒泡的相比,思路其实可以说是反过来了,第一次内循环,获得最小的数的下标位置minindex,然后交换minindex和i的值,也就是把无序数组中最小的值放到有序数组的第1位,有序数组第1位的值放到minindex的位置,也就是每次都取出剩余数组里的最小值,追加到有序的数组的后面,循环结束了升序排序完成。

 

 

       /// <summary>
        /// 插入排序,每次用无序的第一位比较有序列表,插入合适的位置
        /// </summary>
        /// <param name="array"></param>
        public static void charu(int[] array)
        {
            //中间数,用于交换
            int temp = 0;
            //每次取出要比较的值,从数组的第2个开始比,因为第1个跟自己比没有意义
            for (int i = 1; i < array.Length; i++)
            {
                temp = array[i];
                int j = i - 1;
                //一直到取出值大于等于有序的值,或者到下标为0为止
                while (j >= 0 && temp < array[j])
                {
                    //取出的值小,则有序的值往右挪一位
                    array[j + 1] = array[j];
                    //这个不能少,一位一位往从右往左比
                    j--;
                }
                //因为会比较到 有序中小于取出值的位置,所以这里的j=上面的j-1,因此要+1才是需要插入的下标j
                array[j + 1] = temp;
                Console.WriteLine(string.Join(',', array));
            }
        }

插入排序,取出a[n]的值temp,跟a[n-1]比较,如果a[n-1]>temp,则将a[n-1]的值赋给a[n],然后下标前移一位,继续比较a[n-2]和temp,如果a[n-2]>temp,那么将a[n-2]的值赋给a[n-1],直到遇到a[n-m]<temp或者下标小于0为止,也就是每次取出无序数组的第一个值,在有序数组中从右往左一个一个比较,找到比它小的位置后就暂时放下(因为这很可能并不是它的实际位置),每次循环时都会在有序数组里找到一个合适的位置插入值,当整个无序数组都放入有序数组后,整个数组排序完成。

 这三个算法的时间复杂度都是O(n^2)

posted @ 2021-05-22 20:46  luytest  阅读(52)  评论(0编辑  收藏  举报