使用循环和链表完成的归并排序

package com.sort;

public class guibing {
     
    public static  void main(String[] args) {
     
        int[] arr = new int[]{
     34,4,90,5,332,565,12,4,32,56,21,1,34,24,32,1};
        sort(arr);
    }
    public  static  void sort(int[] arr){
     
        //使用链表来归并排序,第一步,将数组转化为链表
        Node[] noarr=new Node[arr.length];
        for(int i=0;i<arr.length;i++){
     
            Node no=new Node(arr[i]);
            noarr[i] = no;
        }
        //开始循环归并,每次循环完成一个步长的合并
        while(true){
     
            //每次合并完之后链表都会变为原来的一半,直到合并的步长为1时停止合并
            int newlength = noarr.length/2;
            //如果链表是奇数,要+1
            if(newlength*2 < noarr.length){
     
                newlength++;
            }
            Node[] newarr = new Node[newlength];
            //开始合并链表
            for(int i=0,num=0;i<noarr.length;i+=2){
     
                Node no1=noarr[i];
                //如果链表是奇数的化,直接将no1放入合并后的链表即可,因为没有no2了
                if(i+1 >= noarr.length){
     
                    newarr[num] = no1;
                    break;
                }
                Node no2 = noarr[i+1];
                Node no3= merge(no1,no2);
                newarr[num] = no3;
                num++;
            }
            //每次合并完,要将指向重新指为原来的链表noarr
            noarr=newarr;
            //子链表长度为一,结束归并,排序已经拍好了
            if(newlength==1) break;
        }
        System.out.println(noarr[0]);
    }
    //两个链表的归并操作
    public  static Node merge(Node no1,Node no2){
     
        //确定指向的第一个节点
        Node result = null;
        if(no1.value < no2.value){
     
            result=no1;
            no1=no1.next;
        }else {
     
            result=no2;
            no2=no2.next;
        }
        //设置游标
        Node flag=result;
        while (no1!=null){
     
            if(no2!=null){
     
                if(no1.value<no2.value){
     
                    flag.next=no1;
                    no1=no1.next;
                }else {
     
                    flag.next=no2;
                    no2=no2.next;
                }
                flag=flag.next;
            }else{
     
                //如果no2空了,no1没有,将no1剩下的节点全部加到要返回的链表上即可
                flag.next=no1;
                break;
            }
        }
        //如果循环结束no1空了no2没有,将no2剩下的节点全部加到要返回的链表上即可
        if(no2!=null){
     
            flag.next=no2;
        }
        //返回头节点的指向
        return  result;
    }
}

Node类如下:

package com.sort;

public class Node {
     
    int value;
    Node next;
    Node(int value){
     
        this.value=value;
    }

    @Override
    public String toString() {
     
        return "Node{" +
                "value=" + value +
                ", next=" + next +
                '}';
    }
}

你可能感兴趣的:(java基础,算法,数据结构,合并排序)