mysql 的 归并排序_排序篇 - 归并排序的实现

归并排序,使用分治算法实现的一种高效的排序排序算法,时间复杂度为O(N*logN) 这已经是比较排序最好的结果了(任何一种排序算法都需要omega(N!)次比较)。

算法就不讲解了,谷歌一下,这里给出C和Java的实现。(代码已经用了很久了,可以直接拿来用,维基百科的Java实现也是我写的,已泛型化)。

C的实现:

/*

* merge sort implements functions.

*

* @author chenxin

* @see http://www.webssky.com

*/

#include

#include "jsort.h"

/*

* a static function to merge two half subarray.

*

* @param *__char the pointer of the array to be sort.

* @param *tmp the temp array.

* @param size the bytes of one item.

* @param left the start positon from the left half.

* @param right the right position from the right half.

* @param end the right-most index of the right half.

*/

static void merge( unsichar_t *__char, unsichar_t *tmp, size_t size,\

compare_fn_t comp, size_t left, size_t right, size_t end ) {

register size_t ptmp = left;

register size_t lEnd = right - 1;

register size_t pos = left;

register unsichar_t *ltmp, *rtmp;

//merge the two half subarray.

while ( left <= lEnd && right <= end ) {

if ( comp( (ltmp = __char + left * size ) , (rtmp = __char + right * size) ) < 0 ) {

copy_value_to( ltmp, tmp + pos * size, size );

left++;

} else {

copy_value_to( rtmp, tmp + pos * size, size );

right++;

}

pos++;

}

//copy the rest of the left

while ( left <= lEnd ) {

copy_value_to( __char + left * size, tmp + pos * size, size );

left++; pos++;

}

//copy the rest of the right

while ( right <= end ) {

copy_value_to( __char + right * size, tmp + pos * size, size );

right++; pos++;

}

//copy the items back from the temp array to the old one.

while ( ptmp <= end ) {

copy_value_to( tmp + ptmp * size, __char + ptmp * size, size );

ptmp++;

}

}

/*

* a static function to make a recursive call.

*

* @param *__char the pointer of the array.

* @param *tmp the temp array.

* @param size the bytes of one item.

* @param comp the compare function pointer.

* @param left the left-most index of the subarray.

* @param right the right-most index of the subarray.

*/

static void merge_recursive( unsichar_t *__char, unsichar_t *tmp,\

size_t size, compare_fn_t comp, size_t left, size_t right ) {

if ( left < right ) {

register size_t median = ( left + right ) / 2;

merge_recursive( __char, tmp, size, comp, left, median );//merge the left half

merge_recursive( __char, tmp, size, comp, median + 1, right );//merge the right half

merge( __char, tmp, size, comp, left, median + 1, right );

}

}

/*

* merge sort algorithm.

*

* @param *a the pointer of the array to be sort.

* @param len the length of the array.

* @param size the bytes of one element.

* @param comp the compare function pointer.

*/

void merge_sort( void *a, size_t len, size_t size, compare_fn_t comp ) {

unsichar_t *tmp = ( unsichar_t * ) calloc( len, size );

unsichar_t *__ca = ( unsichar_t * ) a;

merge_recursive( __ca, tmp, size, comp, 0, len - 1);

//free the memory

free( tmp );

}

jsort.h头文件可以在"排序篇 - 插入排序的实现"中找到。

Java的实现:

/**

* merge sort algorithm.

*

* @param arr an array of Comparable item.

*/

@SuppressWarnings("unchecked")

public static > void mergeSort( T[] arr ) {

/*if ( arr.length < 15 ) {

insertionSort( arr );

return;

}*/

T[] tmpArr = (T[]) new Comparable[arr.length];

mergeSort(arr, tmpArr, 0, arr.length - 1);

}

/**

* internal method to make a recursive call.

*

* @param arr an array of Comparable items.

* @param tmpArr temp array to placed the merged result.

* @param left left-most index of the subarray.

* @param right right-most index of the subarray.

*/

private static >

void mergeSort( T[] arr, T[] tmpArr,

int left, int right ) {

//recursive way

if ( left < right ) {

int center = ( left + right ) / 2;

mergeSort(arr, tmpArr, left, center);

mergeSort(arr, tmpArr, center + 1, right);

merge(arr, tmpArr, left, center + 1, right);

}

//loop instead

/*int len = 2, pos;

int rpos, offset, cut;

while ( len <= right ) {

pos = 0;

offset = len / 2;

while ( pos + len <= right ) {

rpos = pos + offset;

merge( arr, tmpArr, pos, rpos, rpos + offset - 1 );

pos += len;

}

//merge the rest

cut = pos + offset;

if ( cut <= right )

merge( arr, tmpArr, pos, cut, right );

len *= 2;

}

merge( arr, tmpArr, 0, len / 2, right );*/

}

/**

* internal method to merge the sorted halves of a subarray.

*

* @param arr an array of Comparable items.

* @param tmpArr temp array to placed the merged result.

* @param leftPos left-most index of the subarray.

* @param rightPos right start index of the subarray.

* @param endPos right-most index of the subarray.

*/

private static >

void merge( T[] arr, T[] tmpArr,

int lPos, int rPos, int rEnd ) {

int lEnd = rPos - 1;

int tPos = lPos;

int leftTmp = lPos;

while ( lPos <= lEnd && rPos <= rEnd ) {

if ( arr[lPos].compareTo( arr[rPos] ) <= 0 )

tmpArr[ tPos++ ] = arr[ lPos++ ];

else

tmpArr[ tPos++ ] = arr[ rPos++ ];

}

//copy the rest element of the left half subarray.

while ( lPos <= lEnd )

tmpArr[ tPos++ ] = arr[ lPos++ ];

//copy the rest elements of the right half subarray. (only one loop will be execute)

while ( rPos <= rEnd )

tmpArr[ tPos++ ] = arr[ rPos++ ];

//copy the tmpArr back cause we need to change the arr array items.

for ( ; rEnd >= leftTmp; rEnd-- )

arr[rEnd] = tmpArr[rEnd];

}

有递归的实现,也有非递归的实现,但是通过测试发现,递归的实现好像实际效率还高一点。也许和我的实现有关吧。

有问题我们一起讨论。

13.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值