算法 冒泡排序,选择排序,插入排序
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)