第一篇博客实现了三种最基本最简单的排序算法,本篇文章将在这三种算法的基础上稍微演变一下。
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