[英]Recursive MergeSort on a Linked List using Java
我在網上搜索了Java中合並排序算法的良好簡潔方法,以發現使用遞歸的鏈表。
我找不到一個不錯的,所以我試圖在這里實現。 但我卡住了。
這是我到目前為止的內容:
public List mergeSortList(Node head, Node tail) {
if ((head == null) || (head.next == null))
return;
Node middle = this.findMiddle(head);
List left = mergeSortList(this.head, middle);
List right = mergeSortList(middle.next, tail);
return merge(left, right);
}
private List merge(List left, List right) {
List returnedList = new LinkedList();
}
private Node findMiddle(Node n) {
Node slow, fast;
slow = fast = n;
while (fast != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
有人可以幫我糾正任何錯誤,請填寫存根。
謝謝
第一個錯誤是在下面:
while(fast != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
}
考慮到沒有元素為奇數的情況, fast.next.next
, fast.next
可以為null。
這是修改后的代碼:
while(fast != null && fast.next.next != null)
{
slow = slow.next;
if(fast.next!=null)
fast = fast.next.next;
else break;
}
這是另一個修改:
public List mergeSortList(Node head)
{
if ( (head == null) || (head.next == null))
return head;
Node middle = this.findMiddle(head);
Node first = head;
Node second = middle.next;
middle.next = null;
Node left = mergeSortList(first);
Node right = mergeSortList(second);
return merge(left, right);
}
說明:您不需要將tail傳遞給該函數,您可以將中間的列表分成兩個以null結尾的單獨列表。 遞歸兩個列表后,只需重新連接它們,以防止丟失原始列表
這是LinkedList上Merge Sort的干凈簡單的實現
public class MergeSortLinkedList {
static class Node {
Node next;
int value;
Node(int value) {
this.value = value;
}
}
public static void main(String[] args) {
Node head = new Node(10);
head.next = new Node(5);
head.next.next = new Node(2);
head.next.next.next = new Node(1);
head.next.next.next.next = new Node(6);
head.next.next.next.next.next = new Node(8);
head.next.next.next.next.next.next = new Node(3);
head.next.next.next.next.next.next.next = new Node(2);
print(head);
Node sortedHead = mergeSort(head);
print(sortedHead);
}
static void print(Node head) {
Node tmp = head;
while (tmp != null) {
System.out.print(tmp.value + "->");
tmp = tmp.next;
}
System.out.println();
}
static Node getMiddle(Node head) {
if (head == null || head.next == null) {
return head;
}
Node slow = head;
Node fast = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
static Node sortedMerge(Node left, Node right) {
if (left == null) {
return right;
}
if (right == null) {
return left;
}
if (left.value < right.value) {
left.next = sortedMerge(left.next, right);
return left;
} else {
right.next = sortedMerge(left, right.next);
return right;
}
}
static Node mergeSort(Node head) {
if (head == null || head.next == null) {
return head;
}
Node middle = getMiddle(head);
Node middleNext = middle.next;
middle.next = null;
Node left = mergeSort(head);
Node right = mergeSort(middleNext);
return sortedMerge(left, right);
}
}
這看起來是一個好的開始。 您的merge方法將像其他任何合並排序實現一樣工作,除了您要處理列表而不是整數。
您需要做的是:
嘗試一下(發布更新的代碼),我們將很樂意為您提供更多幫助。
解決方案分為兩種方法,第一種方法是遞歸方法,即我們從main()調用的方法,然后使用快速指針和慢速指針技術划分列表(慢速走一個時快走2步),現在用兩個列表遞歸調用自身,並合並使用第二種方法mergeSortedList返回列表,我們也在遞歸中一次又一次地調用mergeSortedList,所以最后,當每個列表中只剩下一個元素時,我們將它們進行比較並以正確的順序加在一起。
ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode fast = head;
ListNode slow = head;
// get in middle of the list :
while (fast.next!= null && fast.next.next !=null){slow = slow.next; fast = fast.next.next;}
fast = slow.next;
slow.next=null;
return mergeSortedList(sortList(head),sortList(fast));
}
ListNode mergeSortedList(ListNode firstList,ListNode secondList){
ListNode returnNode = new ListNode(0);
ListNode trackingPointer = returnNode;
while(firstList!=null && secondList!=null){
if(firstList.val < secondList.val){trackingPointer.next = firstList; firstList=firstList.next;}
else {trackingPointer.next = secondList; secondList=secondList.next;}
trackingPointer = trackingPointer.next;
}
if (firstList!=null) trackingPointer.next = firstList;
else if (secondList!=null) trackingPointer.next = secondList;
return returnNode.next;
}
}
Java中的工作解決方案。 轉到下面的鏈接:
import java.util.*;
import java.lang.*;
import java.io.*;
class Node
{
int data;
Node next;
Node(int data){
this.data = data;
next = null;
}
void append(Node head, int val){
Node temp = new Node(val);
Node cur = head;
if(head == null)
{
return;
}
while(cur.next != null)
{
cur = cur.next;
}
cur.next = temp;
return;
}
void display(){
Node cur = this;
while(cur != null)
{
System.out.print(cur.data + "->");
cur = cur.next;
}
}
}
class Ideone
{
public Node findMiddle(Node head){
if(head == null )
return null;
Node slow, fast;
slow = head;
fast = head;
while(fast != null && fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public Node merge(Node first, Node second){
Node head = null;
while(first != null && second != null){
if(first.data < second.data){
if(head == null){
head = new Node(first.data);
}
else
head.append(head,first.data);
first = first.next;
}
else if(second.data < first.data){
if(head == null){
head = new Node(second.data);
}
else
head.append(head,second.data);
second = second.next;
}
else{
if(head == null){
head = new Node(first.data);
head.append(head,second.data);
}
else{
head.append(head,first.data);
head.append(head,second.data);
}
second = second.next;
first = first.next;
}
}
while(first != null){
if(head == null){
head = new Node(first.data);
}
else
head.append(head,first.data);
first = first.next;
}
while(first != null){
if(head == null){
head = new Node(first.data);
}
else
head.append(head,first.data);
first = first.next;
}
while(second != null){
if(head == null){
head = new Node(second.data);
}
else
head.append(head,second.data);
second = second.next;
}
return head;
}
public Node mergeSort(Node head){
if(head == null)
return null;
if(head.next == null)
return head;
Node first = head;
Node mid = findMiddle(first);
Node second = mid.next;
mid.next = null;
Node left = mergeSort(first);
Node right = mergeSort(second);
Node result = merge(left, right);
return result;
}
public static void main (String[] args) throws java.lang.Exception
{
Node head = new Node(5);
head.append(head,1);
head.append(head,5);
head.append(head,1);
head.append(head,5);
head.append(head,3);
System.out.println("Unsoreted linked list:");
head.display();
Ideone tmp = new Ideone();
Node result = tmp.mergeSort(head);
System.out.println("\nSorted linked list:");
result.display();
}
}
以下是該帖子的Java版本,用於使用合並排序對鏈接列表中的數字進行排序。
import java.util.ArrayList;
public class SortNumbersInLinkedListUsingMergeSort {
Node head;
public static void main(String[] args) {
SortNumbersInLinkedListUsingMergeSort sll = new SortNumbersInLinkedListUsingMergeSort();
// creating an unsorted linked list
sll.head = new Node(2);
sll.head.next = new Node(5);
sll.head.next.next = new Node(3);
sll.head.next.next.next = new Node(-1);
sll.head.next.next.next.next = new Node(1);
printList(sll.head);
sll.head = Merge(sll.head);
printList(sll.head);
}
//
public static Node Merge(Node head){
// if linked list has no or only one element then return
if (head == null || head.next == null){
return null;
}
// split the linked list into two halves, (front and back as two heads)
ArrayList<Node> list = splitIntoSublists(head);
// Recursively sort the sub linked lists
Merge(list.get(0));
Merge(list.get(1));
// merge two sorted sub lists
head = mergeTwoSortedLists(list.get(0), list.get(1));
return head;
}
// method to merge two sorted linked lists
public static Node mergeTwoSortedLists(Node front, Node back){
Node result;
if (front == null){
return back;
}
if (back == null){
return front;
}
if (front.data >= back.data){
result = back;
result.next = mergeTwoSortedLists(front, back.next);
}
else{
result = front;
result.next = mergeTwoSortedLists(front.next, back);
}
return result;
}
// method to split linked list into two list in middle.
public static ArrayList<Node> splitIntoSublists(Node head){
Node slowPointer;
Node fastPointer ;
Node front = null;
Node back = null;
ArrayList<Node> li = new ArrayList<Node>();
if (head == null || head.next == null){
front = head;
back = null;
}
else{
slowPointer= head;
fastPointer = head.next;
while (fastPointer != null && fastPointer.next != null){
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
}
front = head;
back = slowPointer.next;
slowPointer.next = null;
}
li.add(front);
li.add(back);
return li;
}
// method to print linked list
public static void printList(Node head){
Node pointer = head;
while (pointer != null){
System.out.print(pointer.data + " ");
pointer = pointer.next;
}
System.out.println();
}
}
// class to define linked list
class Node{
int data;
Node next;
public Node (int data){
this.data = data;
}
}
這是一個工作示例:
public class MergeSort{
public Node head = null;
public class Node {
int val;
Node next;
public Node () {//Constructor
val = 0;
next = null;
}
public Node (int i) { //constructor
val = i;
next = null;
}
}
public void insert ( int i) { //inserts node at the beginning
Node n = new Node(i);
n.next = head;
head = n;
}
public void printList (Node head) {
while (head != null) {
System.out.println (head.val);
head = head.next;
}
}
public Node sort (Node head) {
if ( head == null || head.next ==null ) return head; // no need to sort if there's no node or only one node in the Linked List
Node mid = find_Mid (head); // find middle of the LinkedList
Node sHalf = mid.next ; mid.next = null; //Splitting into two linked lists
Node h = merge ( sort(head), sort(sHalf) ); //Call merge recursively
return h;
}
public Node merge ( Node n1 , Node n2) {
Node curr = null;
if ( n1 == null )
return n2; //n1 empty
if ( n2 == null )
return n1; // n2 empty
if ( n1.val < n2.val ) {
curr=n1;
curr.next = merge (n1.next, n2); //Call merge recursively
}
else {
curr = n2;
curr.next = merge (n1, n2.next); //Call merge recursively
}
return curr;
}
public Node find_Mid (Node head) {
Node slow = head; Node fast = head;
while ( fast.next != null && fast.next.next != null ) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public static void main(String []args){
System.out.println("Hello World");
MergeSort m = new MergeSort ();
m.insert ( 3 );
m.insert ( 4 );
m.insert ( 16 );
m.insert ( 10 );
m.insert ( 5 );
m.insert ( 1 );
m.insert ( -5 );
m.printList(m.head);
Node n = m.find_Mid (m.head);
System.out.println("Middle is :" + n.val);
m.head = m.sort(m.head);
m.printList(m.head);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.