经典算法之七大排序
【交换排序】:冒泡排序,快速排序 【选择排序】:简单选择排序,堆排序
【插入排序】:简单插入排序,希尔排序 ;归并排序
一:交换排序
public class BubbleSort { public static List<int> Sort(List<int> list) { int temp = 0; //要比较的次数 n-1 for (int i = 0; i < list.Count - 1; i++) { //从底部开始 for (int j = list.Count - 1; j > i; j--) { //往下沉 if (list[j - 1]>list[j]) { temp = list[j]; list[j] = list[j - 1]; list[j - 1] = temp; } } } return list; } }
快排
1 public class QuickSort 2 { 3 public static void Sort(List<int> list,int left,int right) 4 { 5 if (left < right) 6 { 7 int i = Division(list, left, right); 8 Sort(list, left, i - 1); 9 Sort(list,i+1,right); 10 } 11 } 12 13 private static int Division(List<int> list, int left, int right) 14 { 15 //挑选基准元素 16 int baseNum = list[left]; 17 18 while (left < right) 19 { 20 //从数组的右端开始向前找,一直找到比base小的数字为止 21 while (left < right && list[right] >= baseNum) 22 { 23 right = right - 1; 24 } 25 list[left] = list[right]; 26 27 while (left < right && list[left] <= baseNum) 28 { 29 left = left + 1; 30 } 31 list[right] = list[left]; 32 } 33 34 list[left] = baseNum; 35 36 return left; 37 }
二:选择排序:
1 public class SelectionSort 2 { 3 static void Sort(List<int> list) 4 { 5 for (int i = 0; i < list.Count - 1; i++) 6 { 7 //设置tempIndex的下标值 8 int tempIndex = i; 9 for (int j = i + 1; j < list.Count; j++) 10 { 11 if (list[tempIndex] > list[j]) 12 { 13 tempIndex = j; 14 } 15 } 16 17 var tempData = list[tempIndex]; 18 list[tempIndex] = list[i]; 19 list[i] = tempData; 20 } 21 }
/// <summary> /// 堆排序(大根堆,小根堆) /// 大根堆(父结点比孩子结点都要大) /// 小跟堆(父结点比孩子结点都要小) /// </summary> public class HeapSort { public static void Sort(List<int> list) { //list.Count/2-1:就是堆中父节点的个数 for (int i = list.Count / 2 - 1; i >= 0; i--) { HeapAdjust(list, i, list.Count); } //最后输出堆 for (int i = list.Count - 1; i > 0; i--) { //堆顶与当前堆的第i个元素值对调,将对顶踢出,破换堆 int temp = list[0]; list[0] = list[i]; list[i] = temp; //因为两值交换,可能破坏根堆,所以必须重新构造 HeapAdjust(list, 0, i); } } private static void HeapAdjust(List<int> list, int parent, int length) { //temp保留当前父结点 int temp = list[parent]; //得到左孩子(二叉树的定义) int child = 2 * parent + 1; while (child < length) { //如果parent有右孩子,则判断左孩子是否小于右孩子 if (child + 1 < length && list[child] < list[child + 1]) child++; if (temp > list[child]) break; //将较大结点的值赋给父结点 list[parent] = list[child]; //然后将子节点做为父亲节点,已防止是否破坏根堆时重新构造 parent = child; //找到该父亲节点较小的左孩子节点 child = 2 * parent + 1; } //最后将temp值赋给较大的子结点,形成两值交换 list[parent] = temp; } }
三:插入排序
/// <summary> /// 插入排序 /// </summary> /// <remarks> /// 数组被划分为无序数组块和有序数组块 /// </remarks> public class InsertSort { static void Sort(List<int> list) { //无序序列 for (int i = 1; i < list.Count; i++) { var temp = list[i]; int j; //有序序列 for (j = i - 1; j >= 0 && temp < list[j]; j--) { list[j + 1] = list[j]; } list[j + 1] = temp; } } }
public class ShellSort { static void Sort(List<int> list) { //取增量 int step = list.Count/ 2; while (step >= 1) { for (int i = step; i < list.Count; i++) { int temp = list[i]; int j; for (j = i - step; j >= 0 && temp < list[j]; j = j - step) { list[j + step] = list[j]; } list[j + step] = temp; } step = step / 2; } } }
四:归并排序
/// <summary> /// 归并排序的过程 /// 第一: “分”, 就是将数组尽可能的分,一直分到原子级别。 ///第二: “并”,将原子级别的数两两合并排序,最后产生结果。 /// </summary> public class MergeSort { static void Sort(int[] array, int[] temparray, int left, int right) { if (left < right) { //取分割位置 int middle = (left + right) / 2; //先递 Sort(array, temparray, left, middle); Sort(array, temparray, middle + 1, right); //后归 Merge(array, temparray, left, middle + 1, right); } } //数组的两两合并操作 private static void Merge(int[] array, int[] temparray, int left, int middle, int right) { //左指针尾 int leftEnd = middle - 1; //右指针头 int rightStart = middle; //临时数组的下标 int tempIndex = left; //数组合并后的length长度 int tempLength = right - left + 1; //先循环两个区间都没有结束的情况 while ((left <= leftEnd) && (rightStart <= right)) { if (array[left] < array[rightStart]) { temparray[tempIndex++] = array[left++]; } else { temparray[tempIndex++] = array[rightStart++]; } } //判断左序列是否结束 while (left <= leftEnd) temparray[tempIndex++] = array[left++]; while (rightStart <= right) temparray[tempIndex++] = array[rightStart++]; //交换数据 for (int i = 0; i < tempLength; i++) { array[right] = temparray[right]; right--; } } }