您的位置:首页 > 编程语言 > Java开发

单向链表实现归并排序(Java实现)

2015-05-13 19:50 246 查看
因为单链表不能随便访问,只能通过节点的逐步移动访问,因此在数组上应用较多的堆排序和快速排序在链表这块并不适用,而归并排序则能很好的实现,因为归并排序只需要知道中间位置即可,这对于链表来说并不困难。

简单说一下归并排序的思想:

首先将一段链表分成两段,两段长度相等

然后对两段对应的位置进行排序,使用一个临时节点控制链表方向。

使用递归可以非常清晰表达该思想,通过不断递归将有序的两段链表细化到两个节点,排序完成后返回到外层执行该层的有序排列,依次进行后即可实现排序。

下面贴上代码,其中有注释.

/*
* 无环链表实现归并排序
*/
package com.sh.LinkedListMerge;

import java.util.Random;

public class LinkedListMerge {

/**
* @param args
*/
//核心合并操作
public Node merge(Node firstHalf,Node secondHalf)
{
Node current = new Node(-1);//current节点代表临时链表的指针,可移动
Node dummyNode = current;//dummyNode节点指向临时链表的首节点,不可移动,实际上也不移动
while(firstHalf != null && secondHalf != null)
{
if(firstHalf.value <= secondHalf.value)
{
current.next = firstHalf;
firstHalf = firstHalf.next;

}
else
{
current.next = secondHalf;
secondHalf = secondHalf.next;
}

//将current始终作为临时链表最后一个节点
current = current.next;
}
//将剩下的节点加入到临时链表中
current.next = (firstHalf != null) ? firstHalf : secondHalf;

return dummyNode.next;
}

public Node mergeSort(Node head)
{
if(head  == null || head.next == null)
return head;
Node middleNode = this.getMiddleNode(head);
Node secondHalfNode = middleNode.next;
middleNode.next=null;//将两段链表分开
return merge(mergeSort(head),mergeSort(secondHalfNode));
}

public Node getMiddleNode(Node head)
{
if(head == null)
return null;
Node slow = head;
Node fast = head;
while(fast.next != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
}

return slow;
}

//建立链表
public Node buildList(int number)
{
if(number<=0)
return null;
Random r = new Random();
Node head = new Node(r.nextInt(100));
Node pointer = head;
for(int i =1;i<number;i++)
{
Node tem = new Node(r.nextInt(100));//生成一个随机节点
pointer.next = tem;
pointer = tem;
}
return head;
}

public static void main(String[] args) {
// TODO Auto-generated method stub

int number = 10;
LinkedListMerge llm  = new LinkedListMerge();

Node head = llm.buildList(number);
StringBuilder s= new StringBuilder();
for(Node temNode = head ; temNode != null; temNode = temNode.next)
s.append(temNode.value + "->");
String st = s.substring(0,s.length()-2);

System.out.println("原链表为:"+st);
//进行排序并输出
Node sortedHead = llm.mergeSort(head);
StringBuilder sorteds= new StringBuilder();
while(sortedHead!=null){
sorteds.append(sortedHead.value+"->");
sortedHead = sortedHead.next;
}
String sortedst = sorteds.substring(0,sorteds.length()-2);
System.out.println("排序后为:"+sortedst);
}

}


Node节点定义

package com.sh.LinkedListMerge;

public class Node {

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

// TODO Auto-generated constructor stub
}
}


打印输出为

原链表为:70->46->47->46->1->93->39->38->68->63

排序后为:1->38->39->46->46->47->63->68->70->93
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: