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 +
'}';
}
}