【Tree 1】樹形結構數據呈現的遞歸算法實現

1、基本概況

在個人項目中,經常會用到樹形結構的數據,最爲明顯的就是左邊菜單欄,相似於window folder同樣的東西。前端


而我以前一直是藉助前端封裝好的ZTree等工具實現展現,然後臺則一般使用遞歸進行數據的查找。一般,咱們在設計數據庫表的時候,通常會使用三個字段:id,name,pid。以下圖所示:java



2、代碼實現

首先是創建實體類:算法

<span style="font-family:KaiTi_GB2312;font-size:18px;">	private String id;
	private String name;
	private String pid;</span>


編寫實體類的get和set方法。
sql


而後,咱們一般會有如下的幾個方法(一般狀況,封裝粒度不一樣,方法的實現個數和內容也不一樣):數據庫

1,找到全部的父節點

<span style="font-family:KaiTi_GB2312;font-size:18px;">public List<TreeEntity> findAllParents() {
		String sql = "select * from test where pid is null or pid='' ";

		List<TreeEntity> treeList = null;

		try {
			conn = DbUtil.getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();

			treeList = new ArrayList<TreeEntity>();

			while (rs.next()) {
				TreeEntity myTree = new TreeEntity();
				myTree.setId(rs.getString("id"));
				myTree.setName(rs.getString("name"));
				myTree.setPid(rs.getString("pid"));
				treeList.add(myTree);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DbUtil.close(pstmt);
			DbUtil.close(conn);
		}
		return treeList;
	}</span>

2,根據父節點找到全部的孩子

 

<span style="font-family:KaiTi_GB2312;font-size:18px;">public List<TreeEntity> findChildByPid(String pid) {
		String sql = "select * from test where pid='" + pid + "'";

		List<TreeEntity> treeList = null;

		try {
			conn = DbUtil.getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();

			treeList = new ArrayList<TreeEntity>();

			while (rs.next()) {
				TreeEntity myTree = new TreeEntity();
				myTree.setId(rs.getString("id"));
				myTree.setName(rs.getString("name"));
				myTree.setPid(rs.getString("pid"));
				treeList.add(myTree);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DbUtil.close(pstmt);
			DbUtil.close(conn);
		}
		return treeList;
	}</span>


備註:這兩個方法能夠合併,這裏是爲了讓本身更好的理解,而寫了兩個方法。能夠判斷傳入的pid的值,肯定其查找的是父節點,仍是根據父節點查找子節點。
數據結構


3,查看是否存在子節點

<span style="font-family:KaiTi_GB2312;font-size:18px;">	public boolean HasChild(String pid) {
		boolean flag = false;
		String sql = "select * from test where pid='" + pid + "'";
		int count = 0;
		try {
			conn = DbUtil.getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();

			while(rs.next()){
				count++;
			}

			if (count > 0) {
				flag = true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DbUtil.close(pstmt);
			DbUtil.close(conn);
		}

		return flag;
	}</span>


4,使用遞歸拼接父節點的子節點

 

<span style="font-family:KaiTi_GB2312;font-size:18px;">	public void BindChildByParent(String pid, String prefix) {
		if (this.HasChild(pid)) {
			// 獲得當前父節點下的全部孩子
			List<TreeEntity> list = this.findChildByPid(pid);
			// 循環打印當前父節點下的孩子
			for (int i = 0; i < list.size(); i++) {
				System.out.println("|----"+prefix+list.get(i).getName());
				if (this.HasChild(list.get(i).getId())) {
					this.BindChildByParent(list.get(i).getId(),"--");
				}
			}
		}
	}</span>

5,打印樹

 

<span style="font-family:KaiTi_GB2312;font-size:18px;">	public void TreeHtml() {

		// 找到全部的父節點
		List<TreeEntity> treeList1 = this.findAllParents();

		if (treeList1 != null) {
			for (int i = 0; i < treeList1.size(); i++) {
				TreeEntity tree = treeList1.get(i);
				// 打印父節點
				System.out.println("|--" + tree.getName());
				// 綁定孩子
				this.BindChildByParent(tree.getId(), "");
			}
		} else {
			System.out.println("沒有數據!");
		}

	}</span>



6,main方法調用,及實現結果

 

<span style="font-family:KaiTi_GB2312;font-size:18px;">	public static void main(String[] args) {
		Tree tree = new Tree();
		tree.TreeHtml();
	}</span>




3、代碼思考

 

最近,因爲考試,看了數據結構 這本書。首先,我是在想,你們都用的這種方法,到底好在哪兒了,還有就是,爲何在咱們的數據庫設計中,樹的度的概念沒有體現出來。其次是,對於樹的遍歷,有非遞歸的方式,我想也許,我也能夠不用遞歸,就實現樹形結構的數據查找。因而乎,請看下文:數據庫設計


爲何我不想用遞歸:工具

1,通過查證,系統使用遞歸算法,須要系統堆棧處理。當樹的深度很大時,因爲系統支撐不住,會呈現死亡狀態。this

2,遞歸算法的運行效率較低,不管是耗費的計算時間仍是佔用的存儲空間都比非遞歸算法要多。spa

3,最爲直接的緣由:很長一段時間裏,我都不能理解遞歸算法,我總在想,可不能夠用我會的,我喜歡的 方式,去解決我面臨的問題?


遞歸的好處:

結構清晰,可讀性強,並且容易用數學概括法來證實算法的正確性,所以它爲設計算法、調試程序帶來很大方便。 

5、總結

事實證實,對於樹結構的數據搜索,徹底能夠不使用遞歸。我總算完成了我本身的夢想,終於,我能夠不用遞歸,也能夠實現樹結構的查找了。更爲高興的是,事實證實,採用非遞歸的方式,在我接觸到的項目中,它有更大的優點。

下一篇播客,介紹怎麼用非遞歸的方式查找樹結構的數據!至此,我好像以爲本身又變得不同了的感受,我把數據結構這本書的內容,徹底結合到本身的項目中,而且用這些東西,去改造去理解個人代碼。開心,不過還有圖,我不知道怎麼用的,關於圖,我想到了非關係型數據庫,再去驗證吧!

相關文章
相關標籤/搜索