第一篇博客实现了三种最基本最简单的排序算法,本篇文章将在这三种算法的基础上稍微演变一下。
1.快排
光从名字看就知道速度肯定不差,前一篇讲的冒泡排序,怎么看都不算是一种好的排序算法,里面充斥了太多的无谓的交换动作,时间复杂度倒是很稳定o(n^2),但对于排序算法实在说不过去。快排是冒泡排序的改进版,思路就是分治,将一个序列随机按照某个值分成两个子序列,子序列A里面的值全部比该值大,另一个子序列B的值全部比该值小,这听起来像是二叉排序树。然后依次对子序列进行如上操作,很明显快排最简单的实现就是用递归。
看下java实现的快排:
/** * 快速排序,最快O(nlogn) 最差O(n^2) * * @param low * @param high * @param array */ public static void quickSort(int low, int high, int[] array) { if (low >= high) { return; } int i = low; int j = high; // 此处选取的中轴为当前i和j的中间值 int m = (i + j) / 2; int temp = array[m]; array[m] = array[high]; array[high] = temp; // 中轴 int pivotkey = array[high]; while (i < j) { while (i < j && array[i] <= pivotkey) { i++; } array[j] = array[i]; while (i < j && array[j] >= pivotkey) { j--; } array[i] = array[j]; } // 此时i和j相等,替换当前i的值 array[i] = pivotkey; //对左子集做快排 quickSort(low, i - 1, array); //对右子集做快排 quickSort(i + 1, high, array); }
def quickSort(low,high,array): if low > high: return i ,j = low,high m = (i+j)/2 temp = array[m] array[m] = array[high] array[high] = temp pivotkey = array[high] while i < j: while i < j and array[i] < pivotkey: i+=1 array[j] = array[i] while i < j and array[j] >= pivotkey: j-=1 array[i] = array[j] array[i] = pivotkey quickSort(low,i-1,array) quickSort(i+1,high,array)
/** * 二分查找index的插入排序 * @param array */ public static void insertSortBinary(int[] array) { for(int i=1;i<array.length;i++) { int temp = array[i]; int index = binarySearch(0, i, array, array[i]); for(int j=i;j>index;j--) { array[j] = array[j-1]; } array[index] = temp; } } /** * 二分查找微改版 * @param start * @param end * @param array */ public static int binarySearch(int start,int end,int[] array,int value) { while(start <= end) { int mid = (start + end)/2; if(array[mid] == value) { return mid; } else if(array[mid] < value) { start = mid + 1; } else { end = mid - 1; } } return start; }
def insertSortBinary(array): for i in xrange(1,len(array)): index = binarySerach(array,array[i]) for j in range(index,i)[::-1]: array[j] = array[j-1] array[i],array[index] = array[index],array[i] def binarySerach(array,value): low,high = 0,len(array)-1 while low <= high: mid = (low + high)/2 if value == array[mid]: return mid elif value < array[mid] : high = mid -1 else : low = mid + 1 return low希尔排序也是一种插入排序,只不过它先让整体的序列保持部分有序,这样可以加快排序速度,java实现:
/** * 希尔排序,步长g 直接插入排序如果部分有序则速度明显提升,因此考虑 使用分治法,先让子集有序,然后在插入这里有个步长的概念, * 即这个步长内的子集有序,逐步扩大步长,从而做到整体有序 */ public static void shellSort(int[] array) { int[] gs = {5,4,3,2,1}; for(int i=0;i<gs.length;i++) { shellInsert(array, gs[i]); } } /** * 希尔插入,只不过多了步长g * * @param array * @param g */ public static void shellInsert(int[] array, int g) { int temp,j; for (int i = g; i < array.length; i += g) { temp = array[i]; for (j = i - g; j >= 0; j-=g) { if (temp < array[j]) { array[j + g] = array[j]; } else { break; } } array[j+g] = temp; } }python实现:
def shellInsert(array,g): for i in range(g,len(array),g): if array[i] < array[i-g]: temp = array[i] for j in range(0,i,g)[::-1]: if temp < array[j]: array[j+g] = array[j] else: j+=g break array[j] = temp def shellSort(array): gap = [5,4,3,2,1] for x in range(1,6)[::-1]: shellInsert(array,x)
/** * 调整某个子堆,从i节点开始从上到下调整。 将最大值调整到堆顶 * * @param array * @param i */ public static void adjustHeap(int[] array, int i, int len) { int maxIndex = i; // i为叶子及节点 if ((2 * i + 1) >= len) { return; } // 肯定有左孩子 else { // 左孩子大于父亲 if (array[i] < array[2 * i + 1]) { maxIndex = 2 * i + 1; // 有右孩子 } if ((2 * i + 2) < len) { System.out.println("have right"); if (array[maxIndex] < array[2 * i + 2]) { maxIndex = 2 * i + 2; } } } // 交换 if (maxIndex != i) { int temp = array[i]; array[i] = array[maxIndex]; array[maxIndex] = temp; // 递归调整 adjustHeap(array, maxIndex, len); } } /** * 堆的建立过程,是从底像上不断调整的过程,最先开始调整的是最后一个非叶子节点 * * @param array */ public static void createHeap(int[] array) { if (array.length <= 1) { return; } // 从最后一个非叶子节点开始调整 for (int i = array.length / 2 - 1; i >= 0; i--) { adjustHeap(array, i, array.length); } } public static void heapSort(int array[]) { createHeap(array); for (int i = array.length - 1; i >= 0; i--) { int temp = array[0]; array[0] = array[i]; array[i] = temp; adjustHeap(array, 0, i); } }
def heapSort(array): buildHeap(array) for x in xrange(0,len(array)): array[0],array[len(array)-x-1] = array[len(array)-x-1],array[0] adjustHeap(array,len(array)-x-1,0) #from last no leave node def buildHeap(array): x = len(array)/2 - 1 while x>=0: adjustHeap(array,len(array)-x,x) x-=1 #from top to down def adjustHeap(array,size,root): maxIndex = root if (2*root + 1) >= size: return if array[2*root+1] > array[maxIndex]: maxIndex = 2*root + 1 if (2*root+2) < size: if array[2*root+2] > array[maxIndex]: maxIndex = 2*root+2 if maxIndex!=root: array[maxIndex],array[root] = array[root],array[maxIndex] adjustHeap(array,size,maxIndex)
/** * 归并排序,递归调用 * @param array * @param start * @param end */ public static void mergeSort(int[] array,int start,int end) { if(start >= end) { return; } int mid = (start + end)/2; mergeSort(array, start, mid); mergeSort(array,mid + 1,end); merge(array,start,end,mid); } /** * merge方法,合并两个有序的子集 * @param array * @param start * @param end */ public static void merge(int[] array,int start,int end,int mid) { int[] temp = new int[end - start + 1]; int i = start; int j = mid +1; int k = 0; while (i <= mid && j<=end) { if(array[i] < array[j]) { temp[k++] = array[i++]; } else { temp[k++] = array[j++]; } } //拷贝剩余的值到temp while (i<=mid) { temp[k++] = array[i++]; } while (j<=end) { temp[k++] = array[j++]; } System.arraycopy(temp,0,array,start,end - start +1); }python实现:
def mergeSort(array,low,high): if low>=high: return mid = (low+high)/2 mergeSort(array,low,mid) mergeSort(array,mid+1,high) merge(array,low,high,mid) #merge two list def merge(array,low,high,mid): temp_array = [] i,j = low,mid+1 while i<=mid and j<=high: if array[i]<array[j]: temp_array.append(array[i]) i+=1 else: temp_array.append(array[j]) j+=1 while i<=mid: temp_array.append(array[i]) i+=1 while j<=high: temp_array.append(array[j]) j+=1 for x in xrange(0,len(temp_array)): array[low] = temp_array[x] low+=1
原文地址:http://blog.csdn.net/tangyongzhe/article/details/42404413