package sort; import java.util.Arrays; public class MergeSort { public static void main(String args[]) { int a[] = { 8,7,6,5,4,3,2,1}; System.out.println("排序前 :" + Arrays.toString(a)); mergeSort(a); } private static void mergeSort(int[] arr) { mergeSort(arr, new int[arr.length], 0, arr.length - 1); } private static void mergeSort(int[] arr, int[] temp, int left, int right) { if (left < right) { System.out.println("---分 scope ---"); System.out.println("left"+left); System.out.println("right"+right); // System.out.println("开始排序:" + Arrays.toString(arr)); int center = (left + right) / 2; mergeSort(arr, temp, left, center); // 左边 mergeSort(arr, temp, center + 1, right); // 右边 merge(arr, temp, left, center + 1, right); // 合并两个有序 } } /** * 将两个有序表归并成一个有序表 * * @param arr * @param temp 临时数组 * @param leftPos 左边开始下标 * @param rightPos 右边开始下标 * @param rightEnd 右边结束下标 */ private static void merge(int[] arr, int[] temp, int leftPos, int rightPos, int rightEnd) { System.out.println("开始合并两个有序"); int leftEnd = rightPos - 1; // 左边结束下标 int tempPos = leftPos; // 从左边开始算 int numEle = rightEnd - leftPos + 1; // 元素个数 System.out.println("左边开始下标"+leftPos+" 左边结束下标"+leftEnd+" 右边开始下标"+rightPos+" 右边结束下标"+rightEnd); while (leftPos <= leftEnd && rightPos <= rightEnd) { if (arr[leftPos] <= arr[rightPos]) temp[tempPos++] = arr[leftPos++]; else temp[tempPos++] = arr[rightPos++]; } while (leftPos <= leftEnd) { // 左边如果有剩余 temp[tempPos++] = arr[leftPos++]; } while (rightPos <= rightEnd) { // 右边如果有剩余 temp[tempPos++] = arr[rightPos++]; } // 将temp复制到arr for (int i = 0; i < numEle; i++) { arr[rightEnd] = temp[rightEnd]; rightEnd--; } System.out.println("完成合并两个有序:" + Arrays.toString(arr)); System.out.println("------------------------------------"); } }
排序前 :[8, 7, 6, 5, 4, 3, 2, 1]
---分 scope ---
left0
right7
---分 scope ---
left0
right3
---分 scope ---
left0
right1
开始合并两个有序
左边开始下标0 左边结束下标0 右边开始下标1 右边结束下标1
完成合并两个有序:[7, 8, 6, 5, 4, 3, 2, 1]
------------------------------------
---分 scope ---
left2
right3
开始合并两个有序
左边开始下标2 左边结束下标2 右边开始下标3 右边结束下标3
完成合并两个有序:[7, 8, 5, 6, 4, 3, 2, 1]
------------------------------------
开始合并两个有序
左边开始下标0 左边结束下标1 右边开始下标2 右边结束下标3
完成合并两个有序:[5, 6, 7, 8, 4, 3, 2, 1]
------------------------------------
---分 scope ---
left4
right7
---分 scope ---
left4
right5
开始合并两个有序
左边开始下标4 左边结束下标4 右边开始下标5 右边结束下标5
完成合并两个有序:[5, 6, 7, 8, 3, 4, 2, 1]
------------------------------------
---分 scope ---
left6
right7
开始合并两个有序
左边开始下标6 左边结束下标6 右边开始下标7 右边结束下标7
完成合并两个有序:[5, 6, 7, 8, 3, 4, 1, 2]
------------------------------------
开始合并两个有序
左边开始下标4 左边结束下标5 右边开始下标6 右边结束下标7
完成合并两个有序:[5, 6, 7, 8, 1, 2, 3, 4]
------------------------------------
开始合并两个有序
左边开始下标0 左边结束下标3 右边开始下标4 右边结束下标7
完成合并两个有序:[1, 2, 3, 4, 5, 6, 7, 8]
------------------------------------
package sort;
import java.util.Scanner;
public class LinkedInsertSort2 {
static class ListNode {
char val;
ListNode next;
ListNode(char x) {
val = x;
next = null;
}
}
public ListNode mergeSort(ListNode head){
if(head==null || head.next==null) return head;
ListNode mid = getMid(head);//获取链表中间节点
//把链表从之间拆分为两个链表:head和second两个子链表
ListNode second = mid.next;
mid.next = null;
//对两个子链表排序
ListNode left = mergeSort(head);
ListNode right = mergeSort(second);
return merge(right,left);
}
//两个有序链表的归并
private ListNode merge(ListNode l1,ListNode l2){
//辅助节点,排好序的节点将会链接到dummy后面
ListNode dummy = new ListNode((char) 0);
ListNode tail = dummy;//tail指向最后一个排好序的节点
while(l1!=null&&l2!=null){
if(l1.val<=l2.val){
tail.next = l1;
l1 = l1.next;
}else{
tail.next = l2;
l2 = l2.next;
}
tail = tail.next;//移动tail指针
}
if(l1!=null)
tail.next = l1;
else
tail.next = l2;
return dummy.next;
}
//返回链表之间节点
private ListNode getMid(ListNode head){
if(head==null ||head.next==null) return head;
ListNode slow = head;
ListNode faster = head.next;
while(faster!=null&&faster.next!=null){
slow = slow.next;
faster = faster.next.next;
}
return slow;
}
public static void print(ListNode head) {
while(head!=null) {
System.out.println(head.val);
head=head.next;
}
}
public static void main(String[] args) {
ListNode list=new ListNode((char) 0);
// int []ar= {1,5,9,4,8,7,12,3,4,10,14,16,18,19,20,21,2,3};
Scanner sc = new Scanner(System.in);
System.out.println("输入要排序的字符");
char[] ar= sc.next().toCharArray();
// char []ar= {'q','w','e','r','t','y','u','z','d'};
ListNode h=new ListNode((char) -99);
ListNode t=h;
for(int i=0;i<ar.length;i++) {
ListNode node= new ListNode(ar[i]);
h.next=node;
h=h.next;
}
h=t;
h=h.next;
ListNode res=new LinkedInsertSort2().mergeSort(h);
print(res);
}
}
1837

被折叠的 条评论
为什么被折叠?



