算法-常见排序

冒泡排序 【算法-常见排序】以升序来讲,我们需要把最小的一个数通过换位置的方式调到最第一个,那么第二小的数调到第二个位置。每次我们都从最后的一个数arr.lenth - 1进行相邻比较大小,小的往前调,调动至位置i, i从0开始

//排序的时间复杂度n*n个人觉得(n-1)!更为精确 public static void orderByBubble(int a[]) { //先把前面的数排好. for(int i = 0 ; i < a.length - 1 ; i++) { //从最后一个数开始往前冒泡. for(int j = a.length - 1 ; j > i; j--) { //每一轮调换最小的数到最前面》 if(a[j] < a[j-1]) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } } }

选择排序 选择排序比较简单,每次从第arr.lenth - i 个数中找到一个最大或者最小的数,并把该数放到第i个位置
/** * 每次选择一个最小的数放在对应的i位置. * 选择排序.n*n * @param a */ public static void orderBySelect(int a[]) {//这个代表第几个数需要排序.最后n - 1(最后一个)个数是不需要排序的, for(int i = 0 ; i < a.length - 1; i++) { int min = a[i]; for(int j = i + 1 ; j < a.length ; j++ ) { if(min > a[j]) { min = a[j]; } } a[i] = min; //第i个数的序已经排好. } }

直接插入排序 每次将一个无序的数a[i + 1]插入到一个有序的数组a[0] ~ a[i]之间,并且对该数组排序.
/** * 直接插入排序. n * @param a */ public static void orderByDirectInsert(int a[]) { for(int i = 1 ; i < a.length ; i++) { // 在有序的数组里互换位置把己调整到合适的位置. for(int j = i; j > 0 ; j--) { //if(a[n] > a[n - 1] && a[n] < a[n + 1])达到这个条件我们才说OK.终止循环. //如果前面一个数要大,那么我们跟前面一个数换位置 if(a[j - 1] > a[j]) { int temp = a[j - 1]; a[j - 1] = a[j]; a[j] = temp; } } } }

快速排序 快速排序,又名挖坑填数
/** * 时间复杂度n*logn, 空间复杂度logn * 快速排序》,这里就以a[0]为参照.任意数组中的元素为参照. 挖坑填数. * @param a * @param l 初始值通常为0 * @param r 初始值通常为a.length 可以针对某个区间排序. */ public static void orderByQuick(int a[],int l,int r) { if(a == null) { throw new IllegalArgumentException("a[] == null exception"); }if( l< r) { //x只是个参考基数.后面的动作中a[l]最终被放在a[i]上. int i = l,j = r,x = a[l]; while(i < j) { //这表示有一个数比x大了,退出循环的条件,是找到一个比X小的数. while(i < j && a[j] >= x) { j--; } 将这个比x小的数放在左边的位置 a[i++] = a[j]; while (i < j && a[i] < x ) { i++; }; a[j--] = a[i]; } a[i] = x; orderByQuick(a, l, i - 1); //排左边 orderByQuick(a, i+1, r); //排右边. } }

堆排序 二叉树
构建最大堆,调整最大堆,堆逻辑结构表示为一个完全二叉树,从最后一个非叶子节点开始构建最大堆,将堆中的最大元素a[0] 和 最后一个元素互换位置,之后抹去已经调整完成的最后一个元素,剩余的元素继续调整出最大堆,以此循环,直至所有元素调整完毕. 完全二叉树每个节点下标满足公式n = i/2 - 1, n代表节点,i代表节点下面的左孩子. 所以二叉树最后一个节点下标是lastNode = (a.lenth - 1)/2 - 1。
最大堆:即任何节点都比自己左右孩子节点大.由此根节点显然最大.
/** * 这个需要构建最大堆. */ public static void builMaxHeap(int a[],int begain,int end) { int curPointValue = https://www.it610.com/article/a[begain]; int leftIndex = 2*begain + 1; for(int i = leftIndex; i*2 + 1 < end ; ) { //意思是右孩子大于左孩子. if(i + 1 < end && a[i + 1]> a[i]) { 如果右孩子i++,那么下一轮循环,将对该节点下的孩子进行调整 如果没有发生i++,则要调整的是左孩子下的所有节点. i++; } // 取出左右孩子中最大的孩子 if(a[i] > curPointValue) { int temp = a[i]; a[i] = curPointValue; a[begain] = temp; }else //表示当前节点自己就是最大的,不必重排了. break; begain = i; }}/** * 堆排序. 堆是具有某些特性的完全二叉树.每个节点的值要么都大于等于或者小于等于其子节点. * @param a */ public static void orderByHead(int a[]) {//构建最大堆 for(int i = (a.length - 1)/2 ; i >= 0 ; i--) { builMaxHeap(a, i, a.length); }//调整最大堆. for(int j = a.length; j > 0 ; j--) {int temp = a[0]; a[0] = a[j - 1]; a[j-1] = temp; builMaxHeap(a,0, j); }}

    推荐阅读