归并排序和基数排序 及 排序算法比较图
算法中最基础的当数排序了,今天整理记录一下Java中的归并排序和基数排序
这里的排序方式按从小到大讲,由大到小其实就是改变下符号。
接下来讲解一下归并排序的实现
一、归并排序
归并排序,采用递归分治的思想实现具体的逻辑,下面用一张图(引自https://www.cnblogs.com/of-fanruice/p/7678801.html)
从图中我们可以看到递归分支的思想就是将序列通过递归方式分割成单个子序列只有一个元素,然后开始从左到右依次完成相邻两个子序列的合并排序(先对两个子序列中的元素进行排序然后再合并成一个序列),最后得到排序完成的整体序列。
代码实现
public void sort(int[] elements, int left, int right){
if (left >= right) return;
/*通过递归的方式分割数组*/
int mid = (left + right) / 2;
sort(elements, left, mid); // 递归分割左侧
sort(elements, mid + 1, right); // 递归分割右侧
mergeSort(elements, left, mid, right); // 合并排序
}
/**
*
* @param elements 待排元素数组
* @param left 左指针
* @param mid 左指针的边界
* @param right 右指针的边界
*/
private void mergeSort(int[] elements, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left; // 左侧指针
int j = mid + 1; // 右侧指针
int k = 0;
while (i <= mid && j <= right){ //循环判断指针是否指向了边界
if (elements[i] < elements[j]){
temp[k++] = elements[i++];
}else {
temp[k++] = elements[j++];
}
}
//将剩余左侧元素移入临时数组
while (i <= mid){
temp[k++] = elements[i++];
}
//将剩余右侧元素移入临时数组
while (j <= right){
temp[k++] = elements[j++];
}
//将临时数组中的元素放到待排数组的相应位置
for (int n = 0; n < temp.length; n++) {
elements[n + left] = temp[n];
}
二、基数排序
基数排序,下面给出讲基数排序讲的比较好的博客,供自己日后查看。
基数排序详解以及java实现
这篇博客中的例子是有问题的,但是思想讲的还是挺不错的,这里我给出没有问题的例子,供大家参考。
private void radixSort(int[] elements, int d/*数组中最大元素 加 1*/){
int n = 1;//控制取数的第几位
int k = 0;//原数组的下标
int length = elements.length;
int[][] bucket = new int[10][length>10?length:10]; // 桶
int[] order = new int[length>10?length:10]; // 桶中元素的个数
while (n < d){
for (int i = 0; i < length; i++) {
int index = (elements[i] / n) % 10; //得到相应位上的数作为桶下标
bucket[index][order[index]] = elements[i]; //将元素放入对应的桶中
order[index]++; //桶中元素个数加 1 。
}
for (int i = 0; i < length; i++) { // 控制桶的下标
if (order[i] > 0){ //桶中是否有元素
for (int j = 0; j < order[i]; j++) { //将桶中的元素填充进原始数组中
elements[k] = bucket[i][j];
k++; // 控制原始数组的下标
}
order[i] = 0; // 填充完将桶中元素清空
}
}
n *= 10; // 控制取数的第几位
k = 0; // 将原始数组的下标置为0,方便下次填充。
}
}