(4) 归并排序
- 概念:归并(Merge)的含义将两个或两个以上的有序表组合成一个新的有序表,即把若干个有序的子序列合并成整体有序序列。
实例
Java实现(递归)
int[] a = { 1, 54, 6, 3, 78, 34, 12, 45, 56, 100 };
private static int[] mergingSort(int[] a) {
// TODO Auto-generated method stub
sort(a, 0, a.length - 1);
return a;
}
private static void sort(int[] data, int left, int right) {
// TODO Auto-generated method stub
if (left < right) {
int mid = (left + right) / 2;
sort(data, left, mid);
sort(data, mid + 1, right);
merge(data, left, mid, right);
}
}
private static void merge(int[] data, int left, int mid, int right) {
// TODO Auto-generated method stub
int tmparr[] = new int[data.length];
int center = mid + 1;
// third 记录中间数组索引
int third = left;
int tmp = left;
while (left <= mid && center <= right) {
if (data[left] <= data[center]) {
tmparr[third++] = data[left++];
} else {
tmparr[third++] = data[center++];
}
}
// 剩余部分放入中间数组
while (center <= right) {
tmparr[third++] = data[center++];
}
while (left <= mid) {
tmparr[third++] = data[left++];
}
// 将中间数组复制会原数组
while (tmp <= right) {
data[tmp] = tmparr[tmp++];
}
System.out.println(Arrays.toString(tmparr));
}
(5)基数排序
- 概念:基数排序是一种借助多关键字排序的思想对但逻辑关键字进行排序的方法。
- 思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
实例(参考pzhtpf的博客)
4.Java实现
private static int getMaxWeishu(int[] arr) {
// TODO Auto-generated method stub
// 找出最大值
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max)
max = arr[i];
}
// 获得位数
int tmp = 1, d = 1;
while (true) {
tmp *= 10;
if (max / tmp != 0) {
d++;
} else {
break;
}
}
return d;
}
// 基数排序(数组)
private static int[] radixSort(int[] arr) {
// TODO Auto-generated method stub
// 获得位数
int d = getMaxWeishu(arr);
int[][] array = new int[10][arr.length + 1];
for (int i = 0; i < 10; i++) {
array[i][0] = 0; // array[i][0] 记录第i行数据的个数
}
for (int pos = 1; pos <= d; pos++) {
// 分配过程
for (int j = 0; j < arr.length; j++) {
int row = getNumInPos(arr[j], pos);
int col = ++array[row][0];
array[row][col] = arr[j];
}
System.out.println(Arrays.deepToString(array));
// 收集过程
for (int row = 0, i = 0; row < 10; row++) {
for (int col = 1; col <= array[row][0]; col++) {
arr[i++] = array[row][col];
}
array[row][0] = 0;
}
System.out.println(Arrays.toString(arr));
}
// System.out.println(Arrays.toString(arr));
return arr;
}
// pos = 1 表示个位,pos=2表示十位 。。。
private static int getNumInPos(int num, int pos) {
// TODO Auto-generated method stub
int tmp = 1;
for (int i = 0; i < pos - 1; i++) {
tmp *= 10;
}
return (num / tmp) % 10;
}
//链表实现
private static int[] radixSort1(int[] num, int len) {
// TODO Auto-generated method stub
int digit = 1;
int mod;
int divider = 1;
Map<Integer, LinkedList<Integer>> hashmap = new HashMap<Integer, LinkedList<Integer>>();
for (int i = 0; i < 10; i++) {
hashmap.put(i, new LinkedList<Integer>());
}
while (digit <= len) {
// 分配过程
for (int i = 0; i < num.length; i++) {
mod = num[i] / divider % 10;
hashmap.get(mod).add(num[i]);
}
int k = 0;
// 收集过程
for (int i = 0; i < num.length; i++) {
LinkedList<Integer> linkedList = hashmap.get(i);
if (linkedList != null && linkedList.size() > 0) {
for (Integer integer : linkedList) {
num[k++] = integer;
}
}
linkedList.clear();
}
System.out.println(Arrays.toString(num));
divider *= 10;
digit += 1;
}
return num;
}