樹-孩子兄弟表示法的實現

1.什麼是樹

樹狀圖是一種數據結構,它是由n(n>=1)個有限節點組成一個具有層次關係的集合。把它叫做“樹”是因爲它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:
每個節點有零個或多個子節點;沒有父節點的節點稱爲根節點;每一個非根節點有且只有一個父節點;除了根節點外,每個子節點可以分爲多個不相交的子樹;

圖解(靈魂畫師)

2.樹的相關知識

節點的度:一個節點含有的子樹的個數稱爲該節點的度;
葉節點或終端節點:度爲0的節點稱爲葉節點;
非終端節點或分支節點:度不爲0的節點;
雙親節點或父節點:若一個節點含有子節點,則這個節點稱爲其子節點的父節點;
孩子節點或子節點:一個節點含有的子樹的根節點稱爲該節點的子節點;
兄弟節點:具有相同父節點的節點互稱爲兄弟節點;
樹的度:一棵樹中,最大的節點的度稱爲樹的度;
節點的層次:從根開始定義起,根爲第1層,根的子節點爲第2層,以此類推;
樹的高度或深度:樹中節點的最大層次;
堂兄弟節點:雙親在同一層的節點互爲堂兄弟;
節點的祖先:從根到該節點所經分支上的所有節點;
子孫:以某節點爲根的子樹中任一節點都稱爲該節點的子孫。
森林:由m(m>=0)棵互不相交的樹的集合稱爲森林;

遍歷表達法有3種方法:先序遍歷、中序遍歷、後序遍歷

定義一棵樹的根結點層次爲1,其他節點的層次是其父結點層次加1。一棵樹中所有結點的層次的最大值稱爲這棵樹的深度。

3.樹的實現

樹的實現主要有三個:

1.父節點表示法:該方法主要思路是,每個節點存儲父節點的位置,這樣就構成一棵樹

2.孩子鏈表示法:該方法的主要思路是,每個節點用數組存儲孩子位置,不過這個表示法有個致命的缺陷,就是造成大量空間上的浪費,因爲數組最大的長度必定和最多的度相等,但是並不是每個子樹都有那麼多度,所以造成空間上的浪費;

3.兄弟孩子節點表示法:該方法主要思路是:每個節點存儲孩子,兄弟節點位置,本次就用這個表示法實現

下面代碼只實現了添加功能,有空再補上其他功能,其他功能也是大同小異,至於爲什麼有個flag變量,因爲我覺得樹裏存在重複的變量,所以用flag來唯一標識一個樹


package Tree;

/*
 * 樹的整體
 * @author WLNSSS
 * @time 2017.12.22
 * */
public class MyTree<T> {

	// 記錄根樹
	private Node root;

	// 記錄節點數
	private int nodeCount;
	
	// 記錄節點標識的位置
	private int superFlag;

	public MyTree(T data) {
		//初始化,構造器先裝配一個根節點
		root = new Node(data);
	}
	// 在指定位置添加節點
	public void add(T data, int flag) {

		// 定位到指定的位置
		Node point = getNodePost(flag);

		// 錯誤檢查,判斷是否是空,如果空拋出異常
		if (point == null) {
			throw new NullPointerException("沒有此元素");
		} else {

			// 判斷孩子節點空或非空,然後進行不同的操作
			if (point.getChlid() == null) {
				point.setChlid(new Node(data));
			}

			if (point.getChlid() != null) {
				Node temp = point.getChlid();

				Node newNode = new Node(data);
				newNode.setBrother(temp);

				point.setChlid(newNode);

			}
			
			// 元素標識+1
			flag++;
		}
	}

	// 定位節點位置,找出該節點
	public Node getNodePost(int flag) {

		// 調用另外一個複用方法實現
		return getNodePost(flag, root);

	}

	// 定位節點位置,找出該節點
	private Node getNodePost(int flag, Node ponit) {

		// 節點指針,先從root節點開始遞歸
		Node point = root;

		// 當遞歸到一個元素的flag等於要查找的flag則返回當前的指針
		if (point.flag == flag) {
			return point;
		}

		// 若兄弟節點非空,則遞歸取出元素
		if (point.getBrother() != null) {
			return getNodePost(flag, point.getBrother());
		}

		// 若子節點非空,則遞歸取出元素
		if (point.getChlid() != null) {
			return getNodePost(flag, ponit.getChlid());
		}

		// 若沒找到則返回null
		return null;
	}

	/*
	 * 樹的節點(內部類)
	 */
	private class Node {

		// 存儲的數據
		T data;

		

		// 子節點位置
		Node chlid;

		// 兄弟節點位置
		Node brother;

		// 唯一標識該節點的變量
		int flag;
		
		public T getData() {
			return data;
		}

		public void setData(T data) {
			this.data = data;
		}

		public Node getChlid() {
			return chlid;
		}

		public void setChlid(Node chlid) {
			this.chlid = chlid;
		}

		public Node getBrother() {
			return brother;
		}

		public void setBrother(Node brother) {
			this.brother = brother;
		}

		public Node(T data) {
			this(data, null, null,superFlag);
		}

		public Node(T data, Node chlid, Node brother,int flag) {

			this.data = data;
			this.chlid = chlid;
			this.brother = brother;
			this.flag = flag;
		}
		
		

	}
	
	
	public static void main(String[] args) {
		MyTree<Integer> myTree = new MyTree(12);
		myTree.add(1,0);
		myTree.add(2,0);
		System.out.println(myTree.root.chlid.brother.getData());
	}

}



發佈了30 篇原創文章 · 獲贊 9 · 訪問量 6099
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章