排序

排序算法是程序员入门基础算法,下边我们使用Java语言实现常见内部排序算法。

内部排序:待排序记录全部存放在内存中进行排序的过程。

外部排序:待排序记录的数量很大,以至于内存不能容纳全部记录,在排序过程中尚需对外存进行访问的排序过程。

稳定性:若在待排序的序列中 Ai = Aj,排序之前 Ai 领先 Aj ,排序后Ai 和 Aj的相对次序不变, Ai 依然领先 Aj则称此排序算法是稳定的,反之为不稳定。如序列 4 3 4 2 1,用选择排序时,第一趟排序: 第一个4 和 1交换,则两个4之前的相对次序会变化,因此选择排序是不稳定的。

冒泡排序

n个记录进行冒泡排序的方法是:比较相邻两个记录,若逆序则交换这两个值,然后以此类推,第一趟的排序结果是最大的值被交换到第n个记录的位置。然后进行第二趟冒泡排序,对前n-1个记录进行同样的操作,其结果是次大值被交换到第n-1个记录的位置上。冒泡排序最多需要进行n-1趟。若在某趟冒泡排序过程没有进行相邻位置的元素交换处理,则可结束排序过程。

例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8]
第一趟排序时从i=0开始,比较 a[0] 和 a[1],5 > 3 则交换 a[0]和a[1]得到[3,5, 7, 6, 4, 1, 0, 2, 9, 10, 8]继续比较a[1]和a[2] 5 < 7 不用交换,继续向后比较a[2]和a[3]依次类推,最终比较a[9]和a[10]将最大值10放在下标为10的位置;得到第一趟排序结果,第二趟排序将次大值9放在下标为9的位置,...直到数组完全有序为止。
第1趟排序结果:[3, 5, 6, 4, 1, 0, 2, 7, 9, 8, 10]
第2趟排序结果:[3, 5, 4, 1, 0, 2, 6, 7, 8, 9, 10]
第3趟排序结果:[3, 4, 1, 0, 2, 5, 6, 7, 8, 9, 10]
第4趟排序结果:[3, 1, 0, 2, 4, 5, 6, 7, 8, 9, 10]
第5趟排序结果:[1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10]
第6趟排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
上述序列经过6趟排序,得到完全有序序列,此时排序完成即可结束排序过程。

/** 冒泡排序* nums : 待排数组* */public static void bubbleSort(int[] nums) {for (int i = 1; i < nums.length; i++) {boolean temp =false;   // 标记某趟排序是否有值交换for (int j = 0; j < nums.length - i; j++) {if (nums[j] > nums[j + 1]) {              // 相邻元素比较,递增排序nums[j] = nums[j] + nums[j + 1];nums[j + 1] = nums[j] - nums[j + 1];  // 元素交换nums[j] = nums[j] - nums[j + 1];temp = true; // 有值交换}}if (!temp) break; // 无值交换结束排序}}

简单选择排序

n个记录进行简单选择排序就是:通过n-i(1<=i<=n)次关键之间的比较,从n-i+1个记录中选出最小值,并和第i个记录交换。简单说就是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个位置选择第二小的,依次类推,直到第n - 1个元素。

例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8]
第1趟排序在11个元素中找出0放到下标为0的位置,第二趟排序在剩余10个元素中找到1放到下标为1的位置,...总共11个元素则需要10趟排序,其结果如下:
第1趟排序结果: [0, 3, 7, 6, 4, 1, 5, 2, 9, 10, 8]
第2趟排序结果: [0, 1, 7, 6, 4, 3, 5, 2, 9, 10, 8]
第3趟排序结果: [0, 1, 2, 6, 4, 3, 5, 7, 9, 10, 8]
第4趟排序结果: [0, 1, 2, 3, 4, 6, 5, 7, 9, 10, 8]
第5趟排序结果: [0, 1, 2, 3, 4, 6, 5, 7, 9, 10, 8]
第6趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 8]
第7趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 8]
第8趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 8]
第9趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 9]
第10趟排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

/** 简单选择排序* nums :待排序数组* */public static void selectSort(int[] nums) {for (int i = 0; i < nums.length - 1; i++) {int min = i;                        // min记录最小元素下标,默认当前起始元素为最小for (int j = i + 1; j < nums.length; j++) {if (nums[min] > nums[j]) {      // 遍历剩余元素找出最小值min = j;                // 记录最小值数据下标}}if (min != i) {     // 最小值不为当前元素则交换nums[i] = nums[i] + nums[min];nums[min] = nums[i] - nums[min];nums[i] = nums[i] - nums[min];}}}

直接插入排序

直接插入是一种简单排序方法,在插入第i个元素时,R1 、R2 ...、Ri-1已经排好序,这时将Ri依次与Ri-1,Ri-2等进行比较,找到应该插入的位置,插入位置及其后的记录依次向后移动。

  例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8]第一趟排序从第二个元素3开始和它之前的有序序列比较,3<5,则需要将5向后移动;第二趟排序7>5则直接插入当前位置不用移动其他元素,依次类推每趟排序结果如下:第1趟排序结果: [3, 5, 7, 6, 4, 1, 0, 2, 9, 10, 8]第2趟排序结果: [3, 5, 7, 6, 4, 1, 0, 2, 9, 10, 8]第3趟排序结果: [3, 5, 6, 7, 4, 1, 0, 2, 9, 10, 8]第4趟排序结果: [3, 4, 5, 6, 7, 1, 0, 2, 9, 10, 8]第5趟排序结果: [1, 3, 4, 5, 6, 7, 0, 2, 9, 10, 8]第6趟排序结果: [0, 1, 3, 4, 5, 6, 7, 2, 9, 10, 8]第7趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 8]第8趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 8]第9趟排序结果: [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 8]第10趟排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 /** 插入排序* nums  待排序数组* */public static void insertSort(int[] nums) {int temp = 0;int j;for (int i = 1; i < nums.length; i++) {temp = nums[i];                     // 待插入元素for (j = i; j > 0 && temp < nums[j - 1]; j--) { // 寻找插入位置nums[j] = nums[j - 1];  // 插入位置及后元素后移}nums[j] = temp; // 待插入元素放入插入位置}}

希尔排序

希尔排序又称为"缩小增量排序",它是对直接插入排序方法的改进。

希尔排序的基本思想是先将整个待排序列分割成若干子序列,然后分别进行直接插入排序,待整个排序序列基本有序时,再对全体序列进行一次直接插入排序。过程为先取d1作为第一个增量,把序列分成d1个组,即将所有距离为d1倍数序号的值放在同一组,组内进行直接插入排序;然后取第二个增量d2(d2 < d1)重复上述分组和排序工作,以此类推,直到所取增量di=1(di < di-1 <...< d2 < d1),即所有序列放在同一个组进行直接插入排序为止。

  例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8] 增量序列为 incre[5, 3, 1]第1趟排序时增量为5,原序列分为5组分别是[5,1,8]、[3,0]、[7,2]、[6,9]、[4,10] 对各组分别用直接插入排序得到[1,5,8]、[0,3]、[2,7]、[6,9]、[4,10]然后从各组依次取一个元素合并数组得到第一趟排序结果为:[1, 0, 2, 6, 4, 5, 3, 7, 9, 10, 8];第2趟排序取第二个增量为3,则分组为[1,6,3,10][0,4,7,8][2,5,9]重复子数组排序并合并得到第2趟排序结果:[1, 0, 2, 3, 4, 5, 6, 7, 9, 10, 8];最后一趟排序增量为1,即此时数组已相对有序对所有序列进行直接插入排序即可。第1趟排序结果:[1, 0, 2, 6, 4, 5, 3, 7, 9, 10, 8]第2趟排序结果:[1, 0, 2, 3, 4, 5, 6, 7, 9, 10, 8]第3趟排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
/** 希尔排序* nums  待排序数组* incre 增量序列* */public static void shellSort(int[] nums,int[] incre) {int j;for (int i = 0; i < incre.length; i++) { // 从最大增量逐减分组for (int k = incre[i]; k < nums.length; k++) { // 从增量incre[i]向后遍历序列int temp = nums[k];// 序号为incre[i](增量)倍数的为同一组,进行组内直接插入排序for ( j = k; j >= incre[i] && temp < nums[j - incre[i]] ; j-=incre[i]) {nums[j] = nums[j-incre[i]];}nums[j] = temp;}}}

快速排序

快速排序的基本思想是:通过一趟排序将待排序的记录划分为独立的两部分,称为前半区和后半区,其中,前半区中记录的序列值均不大于后半区中的序列值,然后再对这两部分序列值继续进行快速排序,从而使整个序列有序。一趟快速排序的过程称为一次划分,具体做法是:附设两个位置指示变量i和j,它们的初值分别指向序列的第一个值和最后一个值。设枢纽记录(通常是第一个值)pivot,则首先从j所指位置起向前搜索,找到第一个小于pivot的序列值,并将其向前移到i所指示的位置,然后从i所指示的位置向后搜索,找到第一个大于pivot的序列值将其向后移动到j所指示的位置,重复该过程直到i和j相等为止。

  例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8]第一次划分时 取pivot=5,此时i=0,j=10 从右往左找第一个小于pivot的值为2 此时i=0,j=7 将i和j处元素交换位置得到序列:[2, 3, 7, 6, 4, 1, 0, 5, 9, 10, 8];继续从i=0开始向右找第一个大于pivot的值为7,此时i=2,j=7 交换i、j处元素位置得到序列:[2, 3, 5, 6, 4, 1, 0, 7, 9, 10, 8];继续从j=7向左找第一个小于5的数为0 此时i=2,j=6 交换i、j处元素位置得到序列:[2, 3, 0, 6, 4, 1, 5, 7, 9, 10, 8];继续从i=2向右找第一个大于5的数为6 此时 i=3,j=6 交换i、j处元素位置得到序列:[2, 3, 0, 5, 4, 1, 6, 7, 9, 10, 8];继续从j=6开始向左找第一个小于5的数为1 此时 i=3,j=5 交换i、j处元素位置得到序列:[2, 3, 0, 1, 4, 5, 6, 7, 9, 10, 8];继续从i=3向右寻找第一个大于5的数为6 此时 i=6,j=6,这时pivot将数组分为前后两个半区,前半区均小于pivot后半区均大于pivot然后对前后两个半区分别进行快速排序。
 /** 快速排序一次划分* nums 待划分数组* low  左位置* high 右位置* */public static int divide(int[] nums, int low, int high) {int pivot = nums[low];         // 选择第一个元素作为pivotint left = low;int right = high;​while (left < right) {// 从右向左找出比pivot小的数据while (left < right && nums[right] > pivot) {right--;}// 从左向右找出比pivot大的数据while (left < right && nums[left] <= pivot) {left++;}// 没有过界则交换if (left < right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}}// 最终将分界值与当前位置数据交换nums[low] = nums[right];nums[right] = pivot;// 返回分界值所在下标return right;  // left 和 right一样}​​​/** 快速排序(有交换法、挖坑法、单边指针法 这里是交换法)* nums 待排序列* low  数组左下标* high 数组右下标* */public static void quickSort(int[] nums, int low, int high) {if (low >= high) {return;}int index = divide(nums, low, high);    // 返回一次划分的下标quickSort(nums, 0, index - 1); // 左半区快排quickSort(nums, index + 1, high);   // 右半区快排}

归并排序

两路归并就是递归的将序列从中间位置分为两个子序列,直到子序列的元素为一个为止。然后将相邻的两个子序列归并为一个有序序列,不断合并直到原序列全部有序。

  例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8]每个序列会先分成两个子序列,子序列再分子序列直到子序列的元素为1个时进行排序并归并。[5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8] ---> [5, 3, 7, 6, 4, 1] 和 [0, 2, 9, 10, 8][5, 3, 7, 6, 4, 1] ---> [5, 3, 7] 和 [6, 4, 1][5, 3, 7] ---> [5, 3] 和 [7][5, 3]---> [5] 和 [3][5] 和 [3]归并排序后为[3,5]再与[5, 3, 7]的右半子序列[7]合并排序得到[3,5,7]依次类推得到最终有序序列。
  /** * * * * * *归 并 排 序* * * * * ** nums 需排序数组* l 数组 左下标* h 数组 右下标(非数组长度)* */public static void mergeSort(int[] nums, int l, int h) {​if (l == h) return;                // 左等于右 一个元素递归出口int mid = l + (h - l) / 2;            // 计算左右分界点mergeSort(nums, l, mid);         // 左数据有序mergeSort(nums, mid + 1, h);       // 右数据有序int[] newNum = new int[h - l + 1];      // 辅助数据存放左右合并排序后的数据​int m = 0, i = l, j = mid + 1;while (i <= mid && j <= h) {newNum[m++] = nums[i] <= nums[j] ? nums[i++] : nums[j++];   // 左右数组递增排序放入newNum}while (i <= mid) {                 // 右数组先放完,则把左数组剩余依次放入newNum[m++] = nums[i++];}while (j <= h) {                   // 左数组先放完,则把右数组剩余依次放入newNum[m++] = nums[j++];}for (int k = 0; k < newNum.length; k++) {nums[l++] = newNum[k];      // 将a[l,...,h]的元素按排序后放回}}

堆排序

对于n个元素的关键字序列{K1,K2,...Kn},当且仅当满足{Ki<=K2i && Ki<=K2i+1}或{Ki>=K2i && Ki>=K2i+1}时,若将此序列对应的一维数组看成一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不小于(或不大于)其左、右孩子结点的值。因此,在一个堆中,堆元素(即完全二叉树的根结点)必为序列中的最大元素(或最小元素),并且堆中的任一棵树也是堆。

堆排序的基本思想是:对一组待排序的序列。首先按堆的定义排成一个序列(建立初始堆),从而可以输出堆顶最大元素,然后将剩余的元素再调整成新堆,得到次大值,如此反复,直到全部元素有序。

初始堆建立方法:根据完全二叉树的特性,所有i>n/2的元素都没有子结点,因此,初始堆的建立可以从完全二叉树的第n/2个结点开始,向元素下标递减的方向调整,逐步使以Kn/2,....K2,K1为根的子树满足堆的定义。

  例如 序列: a = [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8]对于元素4以后的序列元素无孩子结点,故构建初始堆只考虑 [5, 3, 7, 6, 4]因此构建的初始堆为[10, 9, 7, 6, 8, 1, 0, 2, 5, 4, 3]第1趟排序结果: [9, 8, 7, 6, 4, 1, 0, 2, 5, 3, 10]第2趟排序结果: [8, 6, 7, 5, 4, 1, 0, 2, 3, 9, 10]第3趟排序结果: [7, 6, 3, 5, 4, 1, 0, 2, 8, 9, 10]第4趟排序结果: [6, 5, 3, 2, 4, 1, 0, 7, 8, 9, 10]第5趟排序结果: [5, 4, 3, 2, 0, 1, 6, 7, 8, 9, 10]第6趟排序结果: [4, 2, 3, 1, 0, 5, 6, 7, 8, 9, 10]第7趟排序结果: [3, 2, 0, 1, 4, 5, 6, 7, 8, 9, 10]第8趟排序结果: [2, 1, 0, 3, 4, 5, 6, 7, 8, 9, 10]第9趟排序结果: [1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10]第10趟排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 /** 数组元素调整成大根堆*nums 待排序数组* s  nums[s..len] 序列元素中,除nums[s]外,其余元素均满足大顶堆定义* len 待排序列的最大下标(非数组长度)* */public static void heapAdjust(int[] nums, int s, int len) {int temp = nums[s];        // 临时备份nums[s] 寻找合适位置插入int i;                                          // i 取值 为数组对应完全二叉树的左孩子结点的值for (i = 2 * s + 1; i <= len; i = i * 2 + 1) {  // 沿值较大的孩子结点向下筛选if (i < len && nums[i] < nums[i + 1]) i++;  // i 取左孩子和右孩子较大者的下标if (temp >= nums[i]) break;                 // s 处值满足大顶堆,跳出nums[s] = nums[i];                          // 大值插入根结点s = i;                                      // s 记录待插入元素的位置}nums[s] = temp; // 插入备份元素}​​/** * * * * * 堆 排 序 * * * * ** nums 待排序数组* len 数组长度* */public static void heapSort(int[] nums, int len) {for (int i = len / 2 - 1; i >= 0; i--) {    // len / 2 - 1 以后的元素无子结点heapAdjust(nums, i, len - 1);       // nums[0,....,len-1] 调整为大根堆}for (int i = 1; i < len; i++) {int temp = nums[0];nums[0] = nums[len - i];    // 堆顶元素与序列尾元素交换nums[len - i] = temp;heapAdjust(nums, 0, len - i - 1);  // 待排元素-1,将剩余nums[0,...,len-i-1] 元素重新调整为大根堆。}}

基数排序

基数排序的思想是按组成元素的各个数位的值进行排序,它是分配排序的一种。在该排序方法中将一个元素看成一个d元组,即Ki1,Ki2...,Kid;其中 0 <= Kij< r,i =(1 ~ n),j=(1 ~ d)。r称为基数,待排序列为10进制则r=10,待排序列为八进制则r=8。d是序列元素的最大位数,不足d位的在前边补0。基数排序有MSD(最高位优先),和LSD(最低位优先)。

基本思想:设立r个桶,桶的编号为0,1,...r-1。首先按最低有效位的值把n个元素分配到r个桶中;然后按照桶编号从小到大将各桶中的元素收集起来;接着再按次低有效位的值把刚收集的元素再分配到r个桶中,重复上述分配和收集的过程,直到按照最高有效位分配和收集,这样就得到了一个从小到大的有序序列。

  例如 序列: a = [5,3,7,6,4,1,0,2,9,10,8,11,21,31,41,52,63,74,84,96,101,201,304]序列a最大元素只有三位数,对于基数排序只需三趟排序从最低有效位 个位起 0号桶元素为[0,10]1号桶为[1,11,21, 31, 41, 101, 201]2号桶为[2, 52]3号桶为[3, 63]4号桶为[4, 74, 84, 304]5号桶为[5]6号桶为[6,96]7号桶为[7]8号桶为[8]9号桶为[9]因此第1趟排序结果:[0,10,1,11,21,31, 41, 101, 201, 2, 52, 3, 63, 4, 74, 84, 304, 5, 6, 96, 7, 8, 9]第二趟从十位起0号桶元素为[0, 1, 101, 201, 2, 3, 4, 304, 5, 6, 7, 8, 9]1号桶为[10, 11]2号桶为[21]3号桶为[31]4号桶为[41]5号桶为[52]6号桶为[63]7号桶为[74]8号桶为[84]9号桶为[96]因此第2趟排序结果:[0,1,101,201,2,3, 4, 304, 5, 6, 7, 8, 9, 10, 11, 21, 31, 41, 52, 63, 74, 84, 96]第三趟从百位起0号桶元素为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 31, 41, 52, 63, 74, 84, 96]1号桶为[101]2号桶为[201]3号桶为[304]其他桶无元素,因此第3趟排序结果:[0,1,2,3,4, 5,6, 7, 8, 9, 10, 11, 21, 31, 41, 52, 63, 74, 84, 96, 101, 201, 304]
 /** 基数排序* nums  待排序数组* */public static void radixSort(int[] nums) {int max = nums[0];for (int i = 1; i < nums.length; i++) {if (max<nums[i]) max = nums[i];}int maxLen = (max+"").length(); // 计算数组元素最大位数int[][]bucket = new int[10][nums.length]; //这10个桶按不同的有效位存储有效数字分别为0-9的元素int[]order = new int[10]; //数组order[i]用来表示该有效位是i的元素的个数int k = 0,n = 1,d = 1;  //d=1 按照LSD从最低有效位开始while(d <= maxLen) { // 从最低有效位开始一直到最高有效位重复将元素分配到不同的桶for(int i = 0; i < nums.length; i++) {int lsd = ((nums[i] / n) % 10); // 计算有效位数字bucket[lsd][order[lsd]] = nums[i]; // 元素分配到对应桶order[lsd]++;// 对应桶元素个数增加}for(int i = 0; i < 10; i++) {for(int j = 0; order[i] != 0 && j < order[i]; j++) {nums[k] = bucket[i][j]; // 按桶编号将排序元素重新收集bucket[i][j] = 0;k++;}order[i] = 0;// 清0桶元素个数,进高位重新分配}n *= 10;// 10进制每进位乘10k = 0;d++;// 有效位进高1位}}

总结

排序方法 时间复杂度 辅助空间 稳定性
冒泡排序 O(n2) O(1) 稳定
简单选择排序 O(n2) O(1) 不稳定
直接插入排序 O(n2) O(1) 稳定
希尔排序 O(n1.3) O(1) 不稳定
快速排序 O(nlogn) O(logn) 不稳定
归并排序 O(nlogn) O(n) 稳定
堆排序 O(nlogn) O(1) 不稳定
基数排序 O(d(n+rd)) O(rd) 稳定

Java实现常见排序算法相关推荐

  1. android studio插入数据表中没有_学Java能拿高薪吗 Java中常见排序算法有哪些

    学Java能拿高薪吗?Java中常见排序算法有哪些?作为老牌编程语言,Java拥有广阔的市场占有率,几乎90%以上的大中型互联网应用系统在服务端开发都会首选Java.为了加入到Java这一高薪行业,很 ...

  2. Java 实现常见排序算法

    Java 实现常见排序算法 1. 综述 复习常见排序算法,用Java实现. 2. 代码 1 package cn.edu.tju.scs; 2 3 public class Sort { 4 publ ...

  3. java 实现 常见排序算法(一) 冒泡排序

    大家好,我是烤鸭: 今天分享一下基础排序算法之冒泡排序. 1.     冒泡排序: 原理:比较两个相邻的元素,将较大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第 ...

  4. java 实现 常见排序算法(四)基数排序

    大家好,我是烤鸭: 今天分享一下基础排序算法之基数排序. 1.    基数排序: 原理:基数排序(radix sort)属于"分配式排序"(distribution sort),又 ...

  5. java 实现 常见排序算法(三)快速排序

    大家好,我是烤鸭: 今天分享一下基础排序算法之快速排序.快速排序是内部排序(基于比较排序)中最好的比较算法. 1.     快速排序: 原理:在要排的数(比如数组A)中选择一个中心值key(比如A[0 ...

  6. java 实现 常见排序算法(二) 插入排序

    大家好,我是烤鸭: 今天分享一下基础排序算法之直接插入排序. 1.     直接插入排序: 原理:假设前面的数为有序数列,然后有序数列与无序数列的每个数比较,我们可以从右向左比较 思路:从第2个数开始 ...

  7. Java常见排序算法

    Java常见排序算法 转载于:https://www.cnblogs.com/hfultrastrong/p/7829889.html

  8. Java常见排序算法之插入排序

    一.概述 本节由小千给大家分享Java常见排序算法之插入排序,之前我们说过排序是算法中的一部分.所以我们学习排序也是算法的入门,为了能让大家感受到排序是算法的一部分,我举个例子证明一下:比如麻将游戏, ...

  9. 【十种常见排序算法】

    十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通过比较来决定元素间的相对次序 ...

最新文章

  1. 十二届蓝桥杯省赛B组C++解析(填空题部分)
  2. python学习:函数传参数
  3. niginx查看服务器日志信息,nginx 远程日志服务器
  4. pthread_join
  5. 【顶】Asp无组件生成缩略图(1)
  6. 代码大全和新月神话_神话般的代码
  7. 前端学习(3180):ant-design介绍3
  8. 上下文无关问法cfg
  9. Java编程:将五子棋棋盘内容用稀疏矩阵存储至磁盘,并从中重新读取内容——稀疏数组和算法
  10. Java项目-食堂菜品点评系统(SpringBoot + SpringSecurity + Thymeleaf + Redis)
  11. “2库1平台+N应用”助力智慧机场建设
  12. 分析手段之一:质谱仪GCMS质谱技术
  13. 截止失真放大电路_每周经典电路分析:一个经典实际运放的内部电路分析(1)
  14. 如何用python 对PDF进行拆分,批量修改文件名(根据excel表格)
  15. 武汉理工大学计算机转专业名单,武汉理工大学转专业的限制
  16. python qq机器人 2019_QQ机器人开发
  17. R - 小鑫の日常系列故事(七)——小纸条
  18. 一不留神进了银行黑名单!信用有污点,真的超严重!
  19. 微信-点链接进入公众号关注页
  20. Unity升级到URP渲染管线,

热门文章

  1. 处女篇-我的程序员之路
  2. 人均年薪50万以上,docker到底是什么?为什么这么火?
  3. 产品经理相关资源整理
  4. i5四核八线程怎么样_英特尔八代酷睿i5、i7 CPU处理器评测 4核心8线程威力咋样?...
  5. 给女盆友微信定时消息推送,给她一个大大的情惊喜!!!
  6. git clone 出现fatal: unable to access ‘https://github.com/xxx: Failed to connect to github.com
  7. C小白Jeff头秃番外篇一
  8. Verilog时钟分析
  9. Html5添加SVG生成图案花纹背景样式的js插件教程
  10. TeamCity系列教程(二)-teamcity发布前端项目