Java單向鏈表反轉

Java API中的鏈表是雙向的,我們這裏自己新建一個類代表我們的鏈表元素結點:

class Node {
		int value;
		Node next;

		public Node(int i) {
			setValue(i);
		}

		public Node() {
		}

		public int getValue() {
			return value;
		}

		public void setValue(int value) {
			this.value = value;
		}

		public Node getNext() {
			return next;
		}

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

 然後我們拼接一根鏈表:

Node linkedList = new Node();
		linkedList.setValue(1);
		Node current = linkedList;
		for (int i = 2; i < 10; i++) {
			Node tNode = new Node(i);
			current.setNext(tNode);
			current = tNode;
		}

 這跟鏈表有9個元素,從1一直指向9.

第一種方法需要兩個額外的結點空間,通過循環不停的反向相鄰結點並記錄後續的位置:

	private Node reverse(Node head) {
		Node temp = head.getNext();
		Node flag = temp.getNext();
		head.setNext(null);
		while (flag != null) {
			temp.setNext(head);
			head = temp;
			temp = flag;
			flag = flag.getNext();
		}
		temp.next = head;
		return temp;
	}

 把鏈表頭結點傳入即可實現反轉並返回新的頭結點。

我努力嘗試了使用一個額外結點實現反轉,沒能成功:

	private Node reverse(Node head) {
		Node temp = head.getNext();
		while (temp.getNext() != null) {
			head.getNext().setNext(head);
			head = temp;
			temp = temp.next;
		}
		temp.next = head;
		return temp;
	}

 如果各位有隻使用一個額外空間就能反轉的請留言指點,謝謝。

 

 

第二種反轉方法是使用迭代,需要傳入鏈表的前兩個元素:

	private Node reverseRecur(Node head, Node next) {
		if (next == null) {
			return head;
		}
		if (head.getNext().equals(next)) {//第一次進來
			head.setNext(null);
		}
		if (next.getNext() != null) {
			Node next2 = next.getNext();
			next.setNext(head);
			return reverseRecur2(next, next2);
		}
		next.setNext(head);
		return next;
	}

 我努力嘗試只傳入頭結點來反轉,但是總是不成功:

	private Node reverseRecur(Node head) {
		Node tail = head.getNext();
		if (tail.getNext() != null) {
			Node flag = reverseRecur(tail);
			flag.setNext(head);
			head.setNext(null);
			return head;
		}
		tail.setNext(head);
		head.setNext(null);
		return head;
	}

 

 

我將鏈表長度設置爲10000進行對比,循環的時間和空間都比迭代更好。

爲什麼迭代更常用呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章