遞歸做為一種算法在程序設計語言中廣泛應用。 一個過程或函數在其定義或說明中有直接或間接調用自身的一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。遞歸的能力在於用有限的語句來定義對象的無限集合。一般來說,遞歸需要有邊界條件、遞歸前進段和遞歸返回段。當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回(遞歸簡單說就是程序調用自身的編程技巧,前面說這么多廢話只是為了顯得專業一點)
先看一個簡單求階乘的例子:
public long factorial(long i){//求i if(i==0)return 1; else return i*factorial(i-1);//利用遞歸i!=n*(i-1)!直到0 }
例子一:漢諾塔(經典例子)】
public class super1{ static int count=1; public static void move(char j,char k){ System.out.println("第"+(super1.count++)+"步:把一個杯子從桌子"+j+"拿到杯子"+k); } public static void hanoi(char a,char b,char c,int n){ if(n==1)move(a,c); else{hanoi(a,c,b,n-1); move(a,c); hanoi(b,a,c,n-1); } } public static void main(String[] args){ char a='A',b='B',c='C'; int num=3;//杯子的個數 hanoi(a,b,c,num); } }
輸出如下:
第1步:把一個盤子從桌子A拿到桌子C
第2步:把一個盤子從桌子A拿到桌子B
第3步:把一個盤子從桌子C拿到桌子B
第4步:把一個盤子從桌子A拿到桌子C
第5步:把一個盤子從桌子B拿到桌子A
第6步:把一個盤子從桌子B拿到桌子C
第7步:把一個盤子從桌子A拿到桌子C
例子二:Java 樹父節點遞歸獲取樹子節點
之前做項目遇到樹無法定位准確的子節點就是看這個例子解決的,自己重新寫了一遍這個例子代碼如下:
類一:
package com.kd; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 獲取子節點 */ public class Super2 { private List<Long> returnList = new ArrayList<Long>(); /** * 根據父節點的ID獲取所有子節點 * @param list 分類表 * @param typeId 傳入的父節點ID * @return String */ public String getChildNodes(List<Node> list, Long typeId) { if(list == null && typeId == null) return ""; for (Iterator<Node> iterator = list.iterator(); iterator.hasNext();) { Node node = (Node) iterator.next(); // 一、根據傳入的某個父節點ID,遍歷該父節點的所有子節點 if (node.getParentId()==0 && typeId==node.getId()) { recursionFn(list, node); } // 二、遍歷所有的父節點下的所有子節點 /*if (node.getParentId()==0) { recursionFn(list, node); }*/ } return returnList.toString(); } private void recursionFn(List<Node> list, Node node) { List<Node> childList = getChildList(list, node);// 得到子節點列表 if (hasChild(list, node)) {// 判斷是否有子節點 returnList.add(node.getId()); Iterator<Node> it = childList.iterator(); while (it.hasNext()) { Node n = (Node) it.next(); recursionFn(list, n); } } else { returnList.add(node.getId()); } } // 得到子節點列表 private List<Node> getChildList(List<Node> list, Node node) { List<Node> nodeList = new ArrayList<Node>(); Iterator<Node> it = list.iterator(); while (it.hasNext()) { Node n = (Node) it.next(); if (n.getParentId() == node.getId()) { nodeList.add(n); } } return nodeList; } // 判斷是否有子節點 private boolean hasChild(List<Node> list, Node node) { return getChildList(list, node).size() > 0 ? true : false; } // 本地模擬數據測試 public static void main(String[] args) { long start = System.currentTimeMillis(); List<Node> nodeList = new ArrayList<Node>(); Node node1 = new Node(1l, "蔬菜", 0l); Node node2 = new Node(2l, "水產", 0l); Node node3 = new Node(3l, "畜牧", 0l); Node node4 = new Node(4l, "瓜類", 1l); Node node5 = new Node(5l, "葉類", 1l); Node node6 = new Node(6l, "絲瓜", 4l); Node node7 = new Node(7l, "黃瓜", 4l); Node node8 = new Node(8l, "白菜", 1l); Node node9 = new Node(9l, "蝦", 2l); Node node10 = new Node(10l, "魚", 2l); Node node11 = new Node(11l, "牛", 3l); nodeList.add(node1); nodeList.add(node2); nodeList.add(node3); nodeList.add(node4); nodeList.add(node5); nodeList.add(node6); nodeList.add(node7); nodeList.add(node8); nodeList.add(node9); nodeList.add(node10); nodeList.add(node11); Super2 mt = new Super2(); System.out.println(mt.getChildNodes(nodeList, 1l)); long end = System.currentTimeMillis(); System.out.println("用時:" + (end - start) + "ms"); } }
類二:
package com.kd; /** * 無限級節點模型 */ public class Node { /** * 節點id */ private Long id; /** * 節點名稱 */ private String nodeName; /** * 父節點id */ private Long parentId; public Node() { } Node(Long id, Long parentId) { this.id = id; this.parentId = parentId; } Node(Long id, String nodeName, Long parentId) { this.id = id; this.nodeName = nodeName; this.parentId = parentId; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } public String getNodeName() { return nodeName; } public void setNodeName(String nodeName) { this.nodeName = nodeName; } }