第一篇博客实现了三种最基本最简单的排序算法,本篇文章将在这三种算法的基础上稍微演变一下。
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);
}
再来看下python的实现:
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
最近这段时间在出差,基本没有时间写博客了,不过还是挤出一点儿时间完成它,不然有些东西没完成,心里总是不舒服。