1. 程式人生 > >幾種連結串列排序演算法的JAVA實現

幾種連結串列排序演算法的JAVA實現

插入排序

在這裡插入圖片描述


首先解釋一下一個概念叫做:前繼節點,即我們要的節點的前一個節點。我當時寫這個演算法的時候一直在猶豫的一點在於我怎麼儲存下個節點的狀態,因為在單向連結串列中的必須要儲存下個節點的狀態才能對當前節點進行操作,而另外一點是我應該怎麼樣利用當前的值和前一個值比較。這是我在做這個題的時候最大的麻煩。參考別人的思路。


插入排序的主要的思想在於:

  1. 利用一個前繼節點的概念去尋找當前值比前一個值大的節點
  2. 對前面插入的內容進行排序,然後我們每次從第一個節點開始遍歷這個連結串列進行比較然後插入。

插入演算法的時間複雜度是O(n^2),空間複雜度是常數項。

public static ListNode insertSortList(ListNode head){
		if(head == null || head.next == null) return head;
		ListNode root = new ListNode(0);//來記錄頭結點
		root.next = head;
		ListNode prevNode = head;//這個是用來作為我們遍歷無序連結串列的前繼節點
		ListNode orderPrev ;//這個用來儲存排序完成的連結串列的前繼節點
		
		ListNode cur;
		while(prevNode != null && prevNode.next != null){
			if(prevNode.val < prevNode.next.val){//這樣的比較就是為了要找到比前繼節點大的當前的節點
				prevNode = prevNode.next;
			}else{
				cur = prevNode.next;//如果找到的話,我們需要儲存當前節點
				prevNode.next = cur.next;//用來儲存當前的值的下一個節點,是為了使得下次迴圈可以實現
				/*
					下面開始進行插入元素
				*/
				orderPrev = root;
				while(orderPrev.next.val < cur.val){
					orderPrev = orderPrev.next;
				}
				/**
					當找到前繼節點以後,注意在連結串列中怎麼才能原地插入元素。
				*/
				cur.next = orderPrev.next;
				orderPrev.next = cur;
			}
		}
		
		return root.next;
	}
	public static void main(String[] args){
		ListNode l1 = new ListNode(-1);
		ListNode l2 = new ListNode(5);
		ListNode l3 = new ListNode(3);
		ListNode l4 = new ListNode(4);
		ListNode l5 = new ListNode(0);
		l1.next = l2;
		l2.next = l3;
		l3.next = l4;
		l4.next = l5;
		l5.next = null;
		ListNode head = insertSortList(l1);
		
		while(head != null){
			System.out.printf(head.val+" ");
			head = head.next;
		}
	}

在這裡插入圖片描述

歸併排序

歸併排序的時間複雜度是O(nlogn)空間複雜度是常數項
歸併排序的主要思想在於:

  1. 利用快慢指標的方法,找到中間的節點
  2. 然後進行歸併排序,歸併排序的具體內容在上面的部落格有介紹。(歸併排序的重點在於:我們要確定遞迴切分的退出的條件在這裡是(head == null || head.next != null)還有就是歸併時候:要注意退出的條件)
public   ListNode sortList(ListNode head){
		if(head == null || head.next == null) return head;
		ListNode slow = head;
		ListNode fast = head;
		while(fast.next != null && fast.next.next != null){
			slow = slow.next;
			fast = fast.next.next;
		}
		ListNode right = slow.next;
		slow.next = null;
		ListNode left = sortList(head);
		right = sortList(right);
		head = mergeList(left,right);
		return head;
	}
	public  ListNode mergeList(ListNode left,ListNode right){
		if(left == null){
			return right;
		}
		if(right == null){
			return left;
		}
		ListNode result = null;
		if(left.val < right.val){
			result = left;
			left.next = mergeList(left.next,right);
		}else{
			result = right;
			right.next = mergeList(left,right.next);
		}
		return result;
	}
	public static void main(String[] args){
		ListNode l1 = new ListNode(-1);
		ListNode l2 = new ListNode(5);
		ListNode l3 = new ListNode(3);
		ListNode l4 = new ListNode(4);
		ListNode l5 = new ListNode(0);
		l1.next = l2;
		l2.next = l3;
		l3.next = l4;
		l4.next = l5;
		l5.next = null;
		ListNode head = sortList(l1);
		
		while(head != null){
			System.out.printf(head.val+" ");
			head = head.next;
		}
	}