欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java數(shù)據(jù)結(jié)構(gòu)之樹基本概念解析及代碼示例

 更新時(shí)間:2017年11月21日 16:47:40   作者:牛頭人  
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)之樹基本概念解析及代碼示例,介紹了樹的定義,基本術(shù)語(yǔ),主要操作及實(shí)現(xiàn)等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可了解下。

Java中樹的存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn) 一、樹 樹與線性表、棧、隊(duì)列等線性結(jié)構(gòu)不同,樹是一...節(jié)點(diǎn)與節(jié)點(diǎn)之間的父子關(guān)系,可以為每個(gè)節(jié)點(diǎn)增加一個(gè)parent域,用以記錄該節(jié)點(diǎn)的父點(diǎn)

樹是一種抽象數(shù)據(jù)類型(ADT)或是實(shí)作這種抽象數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu),用來(lái)模擬具有樹狀結(jié)構(gòu)性質(zhì)的數(shù)據(jù)集合。它是由n(n>0)個(gè)有限節(jié)點(diǎn)組成一個(gè)具有層次關(guān)系的集合。把 它叫做“樹”是因?yàn)樗雌饋?lái)像一棵倒掛的樹,也就是說(shuō)它是根朝上,而葉朝下的。

樹定義和基本術(shù)語(yǔ)

定義

樹(Tree)是n(n≥0)個(gè)結(jié)點(diǎn)的有限集T,并且當(dāng)n>0時(shí)滿足下列條件:

(1)有且僅有一個(gè)特定的稱為根(Root)的結(jié)點(diǎn);

(2)當(dāng)n>1時(shí),其余結(jié)點(diǎn)可以劃分為m(m>0)個(gè)互不相交的有限集T1、T2、…、Tm,每個(gè)集Ti(1≤i≤m)均為樹,且稱為樹T的子樹(SubTree)。

特別地,不含任何結(jié)點(diǎn)(即n=0)的樹,稱為空樹。

如下就是一棵樹的結(jié)構(gòu):

基本術(shù)語(yǔ)

結(jié)點(diǎn):存儲(chǔ)數(shù)據(jù)元素和指向子樹的鏈接,由數(shù)據(jù)元素和構(gòu)造數(shù)據(jù)元素之間關(guān)系的引用組成。
孩子結(jié)點(diǎn):樹中一個(gè)結(jié)點(diǎn)的子樹的根結(jié)點(diǎn)稱為這個(gè)結(jié)點(diǎn)的孩子結(jié)點(diǎn),如圖1中的A的孩子結(jié)點(diǎn)有B、C、D
雙親結(jié)點(diǎn):樹中某個(gè)結(jié)點(diǎn)有孩子結(jié)點(diǎn)(即該結(jié)點(diǎn)的度不為0),該結(jié)點(diǎn)稱為它孩子結(jié)點(diǎn)的雙親結(jié)點(diǎn),也叫前驅(qū)結(jié)點(diǎn)。雙親結(jié)點(diǎn)和孩子結(jié)點(diǎn)是相互的,如圖1中,A的孩子結(jié)點(diǎn)是B、C、D,B、C、D的雙親結(jié)點(diǎn)是A。
兄弟結(jié)點(diǎn):具有相同雙親結(jié)點(diǎn)(即同一個(gè)前驅(qū))的結(jié)點(diǎn)稱為兄弟結(jié)點(diǎn),如圖1中B、B、D為兄弟結(jié)點(diǎn)。
結(jié)點(diǎn)的度:結(jié)點(diǎn)所有子樹的個(gè)數(shù)稱為該結(jié)點(diǎn)的度,如圖1,A的度為3,B的度為2.
樹的度:樹中所有結(jié)點(diǎn)的度的最大值稱為樹的度,如圖1的度為3.
葉子結(jié)點(diǎn):度為0的結(jié)點(diǎn)稱為葉子結(jié)點(diǎn),也叫終端結(jié)點(diǎn)。如圖1的K、L、F、G、M、I、J
分支結(jié)點(diǎn):度不為0的結(jié)點(diǎn)稱為分支結(jié)點(diǎn),也叫非終端結(jié)點(diǎn)。如圖1的A、B、C、D、E、H
結(jié)點(diǎn)的層次:從根結(jié)點(diǎn)到樹中某結(jié)點(diǎn)所經(jīng)路徑的分支數(shù)稱為該結(jié)點(diǎn)的層次。根結(jié)點(diǎn)的層次一般為1(也可以自己定義為0),這樣,其它結(jié)點(diǎn)的層次是其雙親結(jié)點(diǎn)的層次加1.
樹的深度:樹中所有結(jié)點(diǎn)的層次的最大值稱為該樹的深度(也就是最下面那個(gè)結(jié)點(diǎn)的層次)。
有序樹和無(wú)序樹:樹中任意一個(gè)結(jié)點(diǎn)的各子樹按從左到右是有序的,稱為有序樹,否則稱為無(wú)序樹。
樹的抽象數(shù)據(jù)類型描述
數(shù)據(jù)元素:具有相同特性的數(shù)據(jù)元素的集合。
結(jié)構(gòu)關(guān)系:樹中數(shù)據(jù)元素間的結(jié)構(gòu)關(guān)系由樹的定義確定。

基本操作:樹的主要操作有

(1)創(chuàng)建樹IntTree(&T)
         創(chuàng)建1個(gè)空樹T。
(2)銷毀樹DestroyTree(&T)
(3)構(gòu)造樹CreatTree(&T,deinition)
(4)置空樹ClearTree(&T)
          將樹T置為空樹。
(5)判空樹TreeEmpty(T)
(6)求樹的深度TreeDepth(T)
(7)獲得樹根Root(T)
(8)獲取結(jié)點(diǎn)Value(T,cur_e,&e)
         將樹中結(jié)點(diǎn)cur_e存入e單元中。
(9)數(shù)據(jù)賦值A(chǔ)ssign(T,cur_e,value)
         將結(jié)點(diǎn)value,賦值于樹T的結(jié)點(diǎn)cur_e中。
(10)獲得雙親Parent(T,cur_e)
        返回樹T中結(jié)點(diǎn)cur_e的雙親結(jié)點(diǎn)。
(11)獲得最左孩子LeftChild(T,cur_e)
        返回樹T中結(jié)點(diǎn)cur_e的最左孩子。
(12)獲得右兄弟RightSibling(T,cur_e)
        返回樹T中結(jié)點(diǎn)cur_e的右兄弟。
(13)插入子樹InsertChild(&T,&p,i,c)
      將樹c插入到樹T中p指向結(jié)點(diǎn)的第i個(gè)子樹之前。
(14)刪除子樹DeleteChild(&T,&p,i)
       刪除樹T中p指向結(jié)點(diǎn)的第i個(gè)子樹。
(15)遍歷樹TraverseTree(T,visit())

樹的實(shí)現(xiàn)

樹是一種遞歸結(jié)構(gòu),表示方式一般有孩子表示法和孩子兄弟表示法兩種。樹實(shí)現(xiàn)方式有很多種、有可以由廣義表的遞歸實(shí)現(xiàn),也可以有二叉樹實(shí)現(xiàn),其中最常見的是將樹用孩子兄弟表示法轉(zhuǎn)化成二叉樹來(lái)實(shí)現(xiàn)。

下面以孩子表示法為例講一下樹的實(shí)現(xiàn):

樹的定義和實(shí)現(xiàn)

package datastructure.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/** 
   * 樹的定義和實(shí)現(xiàn) 
   * @author Administrator 
   * 
   */
public class Tree {
	private Object data;
	private List<Tree> childs;
	public Tree(){
		data = null;
		childs = new ArrayList();
		childs.clear();
	}
	public Tree(Object data) {
		this.data = data;
		childs = new ArrayList();
		childs.clear();
	}
	/** 
     * 添加子樹 
     * @param tree 子樹 
     */
	public void addNode(Tree tree) {
		childs.add(tree);
	}
	/** 
     * 置空樹 
     */
	public void clearTree() {
		data = null;
		childs.clear();
	}
	/** 
     * 求樹的深度 
     * 這方法還有點(diǎn)問(wèn)題,有待完善 
     * @return 樹的深度 
     */
	public int dept() {
		return dept(this);
	}
	/** 
     * 求樹的深度 
     * 這方法還有點(diǎn)問(wèn)題,有待完善 
     * @param tree 
     * @return 
     */
	private int dept(Tree tree) {
		if(tree.isEmpty()) {
			return 0;
		} else if(tree.isLeaf()) {
			return 1;
		} else {
			int n = childs.size();
			int[] a = new int[n];
			for (int i=0; i<n; i++) {
				if(childs.get(i).isEmpty()) {
					a[i] = 0+1;
				} else {
					a[i] = dept(childs.get(i)) + 1;
				}
			}
			Arrays.sort(a);
			return a[n-1];
		}
	}
	/** 
     * 返回遞i個(gè)子樹 
     * @param i 
     * @return 
     */
	public Tree getChild(int i) {
		return childs.get(i);
	}
	/** 
     * 求第一個(gè)孩子 結(jié)點(diǎn) 
     * @return 
     */
	public Tree getFirstChild() {
		return childs.get(0);
	}
	/** 
     * 求最后 一個(gè)孩子結(jié)點(diǎn) 
     * @return 
     */
	public Tree getLastChild() {
		return childs.get(childs.size()-1);
	}
	public List<Tree> getChilds() {
		return childs;
	}
	/** 
     * 獲得根結(jié)點(diǎn)的數(shù)據(jù) 
     * @return 
     */
	public Object getRootData() {
		return data;
	}
	/** 
     * 判斷是否為空樹 
     * @return 如果為空,返回true,否則返回false 
     */
	public Boolean isEmpty() {
		if(childs.isEmpty() && data == null) 
		        return true;
		return false;
	}
	/** 
     * 判斷是否為葉子結(jié)點(diǎn) 
     * @return 
     */
	public Boolean isLeaf() {
		if(childs.isEmpty()) 
		        return true;
		return false;
	}
	/** 
     * 獲得樹根 
     * @return 樹的根 
     */
	public Tree root() {
		return this;
	}
	/** 
     * 設(shè)置根結(jié)點(diǎn)的數(shù)據(jù) 
     */
	public void setRootData(Object data) {
		this.data = data;
	}
	/** 
     * 求結(jié)點(diǎn)數(shù) 
     * 這方法還有點(diǎn)問(wèn)題,有待完善 
     * @return 結(jié)點(diǎn)的個(gè)數(shù) 
     */
	public int size() {
		return size(this);
	}
	/** 
     * 求結(jié)點(diǎn)數(shù) 
     * 這方法還有點(diǎn)問(wèn)題,有待完善 
     * @param tree 
     * @return 
     */
	private int size(Tree tree) {
		if(tree.isEmpty()) {
			return 0;
		} else if(tree.isLeaf()) {
			return 1;
		} else {
			int count = 1;
			int n = childs.size();
			for (int i=0; i<n; i++) {
				if(!childs.get(i).isEmpty()) {
					count += size(childs.get(i));
				}
			}
			return count;
		}
	}
}

樹的遍歷

樹的遍歷有兩種

前根遍歷

(1).訪問(wèn)根結(jié)點(diǎn);

(2).按照從左到右的次序行根遍歷根結(jié)點(diǎn)的第一棵子樹;

后根遍歷

(1).按照從左到右的次序行根遍歷根結(jié)點(diǎn)的第一棵子樹;

(2).訪問(wèn)根結(jié)點(diǎn);

Visit.Java

package datastructure.tree;
import datastructure.tree.btree.BTree;
/** 
   * 對(duì)結(jié)點(diǎn)進(jìn)行操作的接口,規(guī)定樹的遍歷的類必須實(shí)現(xiàn)這個(gè)接口 
   * @author Administrator 
   * 
   */
public interface Visit {
	/** 
     * 對(duì)結(jié)點(diǎn)進(jìn)行某種操作 
     * @param btree 樹的結(jié)點(diǎn) 
     */
	public void visit(BTree btree);
}

order.java

package datastructure.tree;
import java.util.List;
/** 
   * 樹的遍歷 
   * @author Administrator 
   * 
   */
public class Order {
	/** 
     * 先根遍歷 
     * @param root 要的根結(jié)點(diǎn) 
     */
	public void preOrder(Tree root) {
		if(!root.isEmpty()) {
			visit(root);
			for (Tree child : root.getChilds()) {
				if(child != null) {
					preOrder(child);
				}
			}
		}
	}
	/** 
     * 后根遍歷 
     * @param root 樹的根結(jié)點(diǎn) 
     */
	public void postOrder(Tree root) {
		if(!root.isEmpty()) {
			for (Tree child : root.getChilds()) {
				if(child != null) {
					preOrder(child);
				}
			}
			visit(root);
		}
	}
	public void visit(Tree tree) {
		System.out.print("\t" + tree.getRootData());
	}
}

測(cè)試:

要遍歷的樹如下:

package datastructure.tree;
import java.util.Iterator;
import java.util.Scanner;
public class TreeTest {
	/** 
     * @param args 
     */
	public static void main(String[] args) {
		Tree root = new Tree("A");
		root.addNode(new Tree("B"));
		root.addNode(new Tree("C"));
		root.addNode(new Tree("D"));
		Tree t = null;
		t = root.getChild(0);
		t.addNode(new Tree("L"));
		t.addNode(new Tree("E"));
		t = root.getChild(1);
		t.addNode(new Tree("F"));
		t = root.getChild(2);
		t.addNode(new Tree("I"));
		t.addNode(new Tree("H"));
		t = t.getFirstChild();
		t.addNode(new Tree("L"));
		System.out.println("first node:" + root.getRootData());
		//System.out.println("size:" + root.size()); 
		//System.out.println("dept:" + root.dept()); 
		System.out.println("is left:" + root.isLeaf());
		System.out.println("data:" + root.getRootData());
		Order order = new Order();
		System.out.println("前根遍歷:");
		order.preOrder(root);
		System.out.println("\n后根遍歷:");
		order.postOrder(root);
	}
}

結(jié)果:

first node:A
is left:false
data:A
前根遍歷:
A BL E C F DI L H
后根遍歷:
B LE C F D IL H A

結(jié)束語(yǔ):

以上就是本文關(guān)于java數(shù)據(jù)結(jié)構(gòu)之樹基本概念解析及代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

Java編程求二叉樹的鏡像兩種方法介紹

java算法實(shí)現(xiàn)紅黑樹完整代碼示例

java實(shí)現(xiàn)遍歷樹形菜單兩種實(shí)現(xiàn)代碼分享

如有不足之處,歡迎留言指出。

相關(guān)文章

  • 詳解Spring?Security?捕獲?filter?層面異常返回我們自定義的內(nèi)容

    詳解Spring?Security?捕獲?filter?層面異常返回我們自定義的內(nèi)容

    Spring?的異常會(huì)轉(zhuǎn)發(fā)到?BasicErrorController?中進(jìn)行異常寫入,然后才會(huì)返回客戶端。所以,我們可以在?BasicErrorController?對(duì)?filter異常進(jìn)行捕獲并處理,下面通過(guò)本文給大家介紹Spring?Security?捕獲?filter?層面異常,返回我們自定義的內(nèi)容,感興趣的朋友一起看看吧
    2022-05-05
  • Spring中的事件發(fā)布機(jī)制原理解析

    Spring中的事件發(fā)布機(jī)制原理解析

    這篇文章主要介紹了Spring中的事件發(fā)布機(jī)制原理解析,當(dāng)我們關(guān)心spring容器什么時(shí)候刷新,或者想在spring容器刷新的時(shí)候做一些事情,監(jiān)聽關(guān)心的事件,主要就是在ApplicationListener中寫對(duì)應(yīng)的事件,需要的朋友可以參考下
    2023-11-11
  • java模擬post請(qǐng)求發(fā)送json的例子

    java模擬post請(qǐng)求發(fā)送json的例子

    本篇文章主要介紹了java模擬post請(qǐng)求發(fā)送json的例子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • java Unicode和UTF-8之間轉(zhuǎn)換實(shí)例

    java Unicode和UTF-8之間轉(zhuǎn)換實(shí)例

    這篇文章主要介紹了java Unicode和UTF-8之間轉(zhuǎn)換實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • SpringBoot整合MyBatis實(shí)現(xiàn)樂(lè)觀鎖和悲觀鎖的示例

    SpringBoot整合MyBatis實(shí)現(xiàn)樂(lè)觀鎖和悲觀鎖的示例

    這篇文章主要介紹了SpringBoot整合MyBatis實(shí)現(xiàn)樂(lè)觀鎖和悲觀鎖的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • IDEA中Maven的一些常用操作指南

    IDEA中Maven的一些常用操作指南

    intellij idea是一款很流行好用的集成開發(fā)環(huán)境軟件,maven是使用很廣泛的構(gòu)建工具,java開發(fā)者日常少不了與這兩種工具打交道,下面這篇文章主要給大家介紹了關(guān)于IDEA中Maven的一些常用操作指南,需要的朋友可以參考下
    2024-06-06
  • 一文詳解Java如何系統(tǒng)地避免空指針問(wèn)題

    一文詳解Java如何系統(tǒng)地避免空指針問(wèn)題

    新手Java開發(fā)總是經(jīng)??罩羔槞z查,甚至某些老手也會(huì)犯這樣的問(wèn)題,所以這篇文章小編就帶大家一起來(lái)看看如何系統(tǒng)地避免空指針問(wèn)題,希望對(duì)大家有所幫助
    2024-01-01
  • SkyWalking自定義鏈路追蹤實(shí)現(xiàn)步驟

    SkyWalking自定義鏈路追蹤實(shí)現(xiàn)步驟

    本文詳細(xì)介紹了如何使用SkyWalking進(jìn)行自定義鏈路追蹤的步驟,包括POM文件依賴和邏輯業(yè)務(wù)代碼的編寫,文章最后推薦了腳本之家作為進(jìn)一步學(xué)習(xí)的資源
    2024-02-02
  • Springboot如何解決前端請(qǐng)求跨域的問(wèn)題

    Springboot如何解決前端請(qǐng)求跨域的問(wèn)題

    這篇文章主要介紹了Springboot如何解決前端請(qǐng)求跨域的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 基于jmeter實(shí)現(xiàn)跨線程組傳遞token過(guò)程圖解

    基于jmeter實(shí)現(xiàn)跨線程組傳遞token過(guò)程圖解

    這篇文章主要介紹了基于jmeter實(shí)現(xiàn)跨線程組傳遞token,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論