1. 程式人生 > >Java單鏈表反轉 詳細過程

Java單鏈表反轉 詳細過程

Java單鏈表反轉 Java實現單鏈表翻轉

    【尊重】http://blog.csdn.net/guyuealian/article/details/51119499(一)單鏈表的結點結構: 
data域:儲存資料元素資訊的域稱為資料域; 
    next域:儲存直接後繼位置的域稱為指標域,它是存放結點的直接後繼的地址(位置)的指標域(鏈域)。
    data域+ next域:組成資料ai的儲存對映,稱為結點

注意:①連結串列通過每個結點的鏈域將線性表的n個結點按其邏輯順序連結在一起的。   
          ②每個結點只有一個鏈域的連結串列稱為單鏈表(Single Linked List)。
     所謂的連結串列就好像火車車廂一樣,從火車頭開始,每一節車廂之後都連著後一節車廂。
     要實現單鏈表儲存,首先是建立一結點類,其Java程式碼如下:
class Node {
	private int Data;// 資料域
	private Node Next;// 指標域
	public Node(int Data) {
		// super();
		this.Data = Data;
	}
	public int getData() {
		return Data;
	}
	public void setData(int Data) {
		this.Data = Data;
	}

	public Node getNext() {
		return Next;
	}
	public void setNext(Node Next) {
		this.Next = Next;
	}
}
(二)實現反轉的方法:
(1)遞迴反轉法
:在反轉當前節點之前先反轉後續節點。這樣從頭結點開始,層層深入直到尾結點才開始反轉指標域的指向。簡單的說就是從尾結點開始,逆向反轉各個結點的指標域指向,其過程圖如下所示:
   head:是前一結點的指標域(PS:前一結點的指標域指向當前結點)
   head.getNext():是當前結點的指標域(PS:當前結點的指標域指向下一結點)
   reHead:是反轉後新連結串列的頭結點(即原來單鏈表的尾結點)

Java程式碼實現:
package javatest1;
public class javatest1 {
	public static void main(String[] args) {
		Node head = new Node(0);
		Node node1 = new Node(1);
		Node node2 = new Node(2);
		Node node3 = new Node(3);
		head.setNext(node1);
		node1.setNext(node2);
		node2.setNext(node3);

		// 列印反轉前的連結串列
		Node h = head;
		while (null != h) {
			System.out.print(h.getData() + " ");
			h = h.getNext();
		}
		// 呼叫反轉方法
		head = Reverse1(head);

		System.out.println("\n**************************");
		// 列印反轉後的結果
		while (null != head) {
			System.out.print(head.getData() + " ");
			head = head.getNext();
		}
	}

	/**
	 * 遞迴,在反轉當前節點之前先反轉後續節點
	 */
	public static Node Reverse1(Node head) {
		// head看作是前一結點,head.getNext()是當前結點,reHead是反轉後新連結串列的頭結點
		if (head == null || head.getNext() == null) {
			return head;// 若為空鏈或者當前結點在尾結點,則直接還回
		}
		Node reHead = Reverse1(head.getNext());// 先反轉後續節點head.getNext()
		head.getNext().setNext(head);// 將當前結點的指標域指向前一結點
		head.setNext(null);// 前一結點的指標域令為null;
		return reHead;// 反轉後新連結串列的頭結點
	}
}

	class Node {
		private int Data;// 資料域
		private Node Next;// 指標域

		public Node(int Data) {
			// super();
			this.Data = Data;
		}

		public int getData() {
			return Data;
		}

		public void setData(int Data) {
			this.Data = Data;
		}

		public Node getNext() {
			return Next;
		}

		public void setNext(Node Next) {
			this.Next = Next;
		}
	}

(2)遍歷反轉法:遞迴反轉法是從後往前逆序反轉指標域的指向,而遍歷反轉法是從前往後反轉各個結點的指標域的指向。   基本思路是:將當前節點cur的下一個節點 cur.getNext()快取到temp後,然後更改當前節點指標指向上一結點pre。也就是說在反轉當前結點指標指向前,先把當前結點的指標域用tmp臨時儲存,以便下一次使用,其過程可表示如下:
   pre:上一結點
   cur: 當前結點
   tmp: 臨時結點,用於儲存當前結點的指標域(即下一結點)


Java程式碼實現:
package javatest1;
public class JavaTest1 {
	public static void main(String[] args) {
		Node head = new Node(0);
		Node node1 = new Node(1);
		Node node2 = new Node(2);
		Node node3 = new Node(3);

		head.setNext(node1);
		node1.setNext(node2);
		node2.setNext(node3);

		// 列印反轉前的連結串列
		Node h = head;
		while (null != h) {
			System.out.print(h.getData() + " ");
			h = h.getNext();
		}
		// 呼叫反轉方法
		// head = reverse1(head);
		head = reverse2(head);

		System.out.println("\n**************************");
		// 列印反轉後的結果
		while (null != head) {
			System.out.print(head.getData() + " ");
			head = head.getNext();
		}
	}

	/**
	 * 遍歷,將當前節點的下一個節點快取後更改當前節點指標
	 */
	public static Node reverse2(Node head) {
		if (head == null)
			return head;
		Node pre = head;// 上一結點
		Node cur = head.getNext();// 當前結點
		Node tmp;// 臨時結點,用於儲存當前結點的指標域(即下一結點)
		while (cur != null) {// 當前結點為null,說明位於尾結點
			tmp = cur.getNext();
			cur.setNext(pre);// 反轉指標域的指向

			// 指標往下移動
			pre = cur;
			cur = tmp;
		}
		// 最後將原連結串列的頭節點的指標域置為null,還回新連結串列的頭結點,即原連結串列的尾結點
		head.setNext(null);
		
		return pre;
	}
}

class Node {
	private int Data;// 資料域
	private Node Next;// 指標域

	public Node(int Data) {
		// super();
		this.Data = Data;
	}

	public int getData() {
		return Data;
	}

	public void setData(int Data) {
		this.Data = Data;
	}

	public Node getNext() {
		return Next;
	}

	public void setNext(Node Next) {
		this.Next = Next;
	}
}

如果你覺得該帖子幫到你,還望貴人多多支援,鄙人會再接再厲,繼續努力的~