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

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 +
                '}';
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值