【Java】 劍指offer(5) 從尾到頭打印鏈表

本文參考自《劍指offer》一書,代碼採用Java語言。html

 更多:《劍指Offer》Java實現合集java

題目

  輸入一個鏈表的頭結點,從尾到頭反過來打印出每一個結點的值。結點定義以下:node

public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

思路

  結點遍歷順序只能從頭至尾,可是輸出的順序卻爲從尾到頭,是典型的「後進先出」問題,這就要聯想到使用棧,從而也能夠聯想到使用遞歸。ide

測試用例函數

  1.功能測試(單個結點鏈表,多個結點鏈表)post

  2.特殊輸入測試(鏈表爲空)學習

完整Java代碼

import java.util.Stack;

/**
 * 
 * @Description 從尾到頭打印鏈表
 *
 * @author yongh
 * @date 2018年9月10日 下午7:07:23
 */

//題目:輸入一個鏈表的頭結點,從尾到頭反過來打印出每一個結點的值。

public class PrintListInReversedOrder {
	class ListNode{
		int key;
		ListNode next;
		public ListNode(int key) {
			this.key=key;
			this.next=null;
		}
	}
	
	// 採用棧
	public void printListReversingly_Iteratively(ListNode node) {
		Stack<ListNode> stack = new Stack<ListNode>();
		while (node!= null) {
			stack.push(node);
			node=node.next;
		}
		while(!stack.empty()) {
			System.out.println(stack.pop().key);
		}
	}
	
	//採用遞歸
	public void printListReversingly_Recursively(ListNode node) {
		if(node!=null) {
			printListReversingly_Recursively(node.next);
			System.out.println(node.key);
		}else
			return;
		
	}
	
	
	// ==================================測試代碼==================================
	/**
	 * 鏈表爲空
	 */
	public void test1() {
		ListNode aListNode = null;
		System.out.println("採用棧:");
		printListReversingly_Iteratively(aListNode);
		System.out.println("採用遞歸:");
		printListReversingly_Recursively(aListNode);
	}
	
	/**
	 * 多個結點鏈表
	 */
	public void test2() {
		ListNode ListNode1 = new ListNode(1);
		ListNode ListNode2 = new ListNode(2);
		ListNode ListNode3 = new ListNode(3);
		ListNode ListNode4 = new ListNode(4);
		ListNode ListNode5 = new ListNode(5);
		ListNode1.next=ListNode2;
		ListNode2.next=ListNode3;
		ListNode3.next=ListNode4;
		ListNode4.next=ListNode5;
		System.out.println("採用棧:");
		printListReversingly_Iteratively(ListNode1);
		System.out.println("採用遞歸:");
		printListReversingly_Recursively(ListNode1);
	}
	
	/**
	 * 單個結點鏈表
	 */
	public void test3() {
		ListNode ListNode1 = new ListNode(1);
		System.out.println("採用棧:");
		printListReversingly_Iteratively(ListNode1);
		System.out.println("採用遞歸:");
		printListReversingly_Recursively(ListNode1);
	}
	
	public static void main(String[] args) {
		PrintListInReversedOrder demo = new PrintListInReversedOrder();
		System.out.println("test1:");
		demo.test1();
		System.out.println("test2:");
		demo.test2();
		System.out.println("test3:");
		demo.test3();
	}
}

  

test1:
採用棧:
採用遞歸:
test2:
採用棧:
5
4
3
2
1
採用遞歸:
5
4
3
2
1
test3:
採用棧:
1
採用遞歸:
1
PrintListInReversedOrder

 

遞歸部分代碼也能夠像下面這樣寫,注意體會不一樣的遞歸寫法:測試

	// 採用遞歸
	public void printListReversingly_Recursively(ListNode node) {
		// if(node!=null) {
		// printListReversingly_Recursively(node.next);
		// System.out.println(node.key);
		// }else
		// return;
		if (node != null) {
			if (node.next != null) {
				printListReversingly_Recursively(node.next);
			}
			System.out.println(node.key);
		}
	}

   

====================================================================ui

 在牛客網中提交的代碼以下(參考自:grass_stars 的代碼):this

public class Solution {
	ArrayList<Integer> arrayList = new ArrayList<Integer>();
	public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
		if (listNode != null) {
			this.printListFromTailToHead(listNode.next);
			arrayList.add(listNode.val);
		}
		return arrayList;
	}
}

  上面代碼採用的遞歸,很是簡潔,很值得學習。

收穫

  1.對於「後進先出」問題,要快速想到」棧「,也同時想到遞歸。

  2.採用遞歸時,返回的函數值不必定要有賦值操做,只要實現了遍歷的做用就能夠了,上面牛客網的代碼能夠多多學習。

 

 更多:《劍指Offer》Java實現合集

相關文章
相關標籤/搜索