歸并排序

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);

    }

    
    
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值