日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

java树算法_Java数据结构算法(三)树

發(fā)布時(shí)間:2023/12/4 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java树算法_Java数据结构算法(三)树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文旨作于收集整理使用!!

導(dǎo)航

一、樹(shù)

樹(shù)(Tree)是n(n≥0)個(gè)結(jié)點(diǎn)的有限集,n=0稱之為空樹(shù)。在非空樹(shù)種:當(dāng)有且僅有一個(gè)特定的稱為根(Root)的結(jié)點(diǎn); 其余結(jié)點(diǎn)可以劃分為m(m>0)個(gè)互不相交的有限集T1、T2 、…、Tm,每個(gè)集Ti(1≤i≤m)均為樹(shù),且稱為樹(shù)的子樹(shù)(SubTree), 如下圖所示。

根節(jié)點(diǎn):根節(jié)點(diǎn)指沒(méi)有雙親結(jié)點(diǎn)的結(jié)點(diǎn),一棵樹(shù)中最多有一個(gè)根節(jié)點(diǎn)(如A)

葉子結(jié)點(diǎn):沒(méi)有孩子結(jié)點(diǎn)的結(jié)點(diǎn)叫作葉子結(jié)點(diǎn)(如L、M、F)

兄弟結(jié)點(diǎn):擁有相同雙親結(jié)點(diǎn)的所有孩子結(jié)點(diǎn)叫作兄弟結(jié)點(diǎn)(L、M是E的兄弟結(jié)點(diǎn),I、J、K是D的兄弟結(jié)點(diǎn))

結(jié)點(diǎn)的深度:是指從根節(jié)點(diǎn)到該節(jié)點(diǎn)的路徑長(zhǎng)度(O點(diǎn)的深度為3,A—C—G—O)

樹(shù)的高度:是樹(shù)中所有結(jié)點(diǎn)高度的最大值,樹(shù)的深度是樹(shù)中所有結(jié)點(diǎn)深度的最大值,對(duì)于同一棵樹(shù),其深度和高度是相同的,但是對(duì)于各個(gè)結(jié)點(diǎn),其深度和高度不一定相同

二、二叉樹(shù)

二叉樹(shù)(Binary Tree)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集合,該集合或?yàn)榭占?#xff0c;或?yàn)橛梢粋€(gè)根節(jié)點(diǎn)和兩顆互不相交的,分別稱為根節(jié)點(diǎn)的左子樹(shù)和右子樹(shù)的二叉樹(shù)組成。

二叉樹(shù)

所有節(jié)點(diǎn)只有左子樹(shù)的二叉樹(shù)稱為左斜樹(shù),只有右子樹(shù)的二叉樹(shù)稱為右斜樹(shù)。

所有節(jié)點(diǎn)均含左子樹(shù)和右子樹(shù),這樣的二叉樹(shù)稱為滿二叉樹(shù)。

滿二叉樹(shù)

完全二叉樹(shù):若設(shè)二叉樹(shù)的深度為h,除第 h 層外,其它各層 (1~h-1) 的結(jié)點(diǎn)數(shù)都達(dá)到最大個(gè)數(shù),第 h 層所有的結(jié)點(diǎn)都連續(xù)集中在最左邊,這就是完全二叉樹(shù)。

完全二叉樹(shù)

二叉樹(shù)的應(yīng)用:編譯器中的表達(dá)式樹(shù)、用于數(shù)據(jù)壓縮算法中的赫夫曼編碼樹(shù)、支持在集合中查找、插入和刪除,其平均時(shí)間復(fù)雜度為O(lognn)的二叉搜索樹(shù)(BST)、優(yōu)先隊(duì)列(PQ),它支持以對(duì)數(shù)時(shí)間(最壞情況下)對(duì)集合中的最小(或最大)數(shù)據(jù)元素進(jìn)行搜索和刪除;

1、二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)

基本了解了二叉樹(shù)的組成后,我們學(xué)習(xí)怎么樣去存儲(chǔ)二叉樹(shù),了解二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)。

1.1、滿二叉樹(shù)

存儲(chǔ)滿二叉樹(shù)可以使用數(shù)組,我們將上圖中的滿二叉樹(shù)存儲(chǔ)為數(shù)組為[A,B,C,D,E,F,G]),當(dāng)然我們通過(guò)數(shù)組復(fù)原二叉樹(shù)時(shí)也可以按照順序復(fù)原二叉樹(shù)。

1.2、完全二叉樹(shù)

完全二叉樹(shù)和滿二叉樹(shù)的存儲(chǔ)方法相同,上圖中的完全二叉樹(shù)轉(zhuǎn)換為數(shù)組([A,B,C,D,E,F,G,H,I])(圖中最后的H為I)。

1.2、其他二叉樹(shù)

有的二叉樹(shù)既不是滿二叉樹(shù)又不是完全二叉樹(shù)該如何存儲(chǔ)?我們可以將缺少的二叉樹(shù)的葉子節(jié)點(diǎn)用一些特殊的符號(hào)存儲(chǔ),將其轉(zhuǎn)換為完全二叉樹(shù),如下圖所示。

則如上圖中的二叉樹(shù)轉(zhuǎn)換為數(shù)組([A,B,C,D,E,F,G,#.#,H,#,#,#,I,J])

2二叉樹(shù)的遍歷

二叉樹(shù)的遍歷分為前序遍歷、中序遍歷和后序遍歷

3.1 前序遍歷

先遍歷左子樹(shù),再遍歷右子樹(shù)

2.2、 中序遍歷

從根結(jié)點(diǎn)開(kāi)始(注意并不是先訪問(wèn)根結(jié)點(diǎn)),中序遍歷根結(jié)點(diǎn)的左子樹(shù),然后是訪問(wèn)根結(jié)點(diǎn),最后中序遍歷右子樹(shù)

2.3 后序遍歷

從左到右先葉子后結(jié)點(diǎn)的方式遍歷訪問(wèn)左右子樹(shù),最后是訪問(wèn)根結(jié)點(diǎn)

3、實(shí)現(xiàn)二叉樹(shù)

如下,需要構(gòu)建如下二叉樹(shù),并實(shí)現(xiàn)其三種遍歷方法

/**

* 構(gòu)造如下二叉樹(shù)

* A

* B C

* D E G

*

*/

import java.util.List;

/**

* 構(gòu)造如下二叉樹(shù)

* A

* B C

* D E G

*/

public class BinaryTree {

TreeNode root = null;

public BinaryTree() {

root = new TreeNode(0, "A");

}

/**

* 傳統(tǒng)方法構(gòu)造二叉樹(shù)

*/

public void createBinaryTree() {

TreeNode nodeB = new TreeNode(2, "B");

TreeNode nodeC = new TreeNode(3, "C");

TreeNode nodeD = new TreeNode(4, "D");

TreeNode nodeE = new TreeNode(5, "E");

TreeNode nodeF = new TreeNode(6, "F");

root.leftChild = nodeB;

root.rightChild = nodeC;

nodeB.leftChild = nodeD;

nodeB.rightChild = nodeE;

nodeC.rightChild = nodeF;

}

/**

* 出入二叉樹(shù)的數(shù)組,創(chuàng)建二叉樹(shù)

*

* @param size 二叉樹(shù)所有節(jié)點(diǎn)的數(shù)量和

* @param datas 二叉樹(shù)的List集合

* @return 返回創(chuàng)建的節(jié)點(diǎn)

*/

public TreeNode createBinerTree(int size, List datas) {

TreeNode node = null;

if (datas.size() == 0) {

return null;

}

String data = datas.get(0);

if ("#".equals(data)) {

datas.remove(0);

return node;

}

int index = size - datas.size();

node = new TreeNode(index, data);

if (index == 0) {

root = node;

}

datas.remove(0);

node.leftChild = createBinerTree(size, datas);

node.rightChild = createBinerTree(size, datas);

return node;

}

/**

* 前序遍歷

*/

public void preOrder(TreeNode node) {

if (node == null) {

return;

} else {

System.out.println("preOrder data:" + node.getData());

preOrder(node.leftChild);

preOrder(node.rightChild);

}

}

/**

* 中序遍歷

*/

public void midOrder(TreeNode node) {

if (node == null) {

return;

} else {

midOrder(node.leftChild);

System.out.println("midOrder data:" + node.getData());

midOrder(node.rightChild);

}

}

/**

* 后序遍歷

*/

public void postOrder(TreeNode node) {

if (node == null) {

return;

} else {

preOrder(node.leftChild);

preOrder(node.rightChild);

System.out.println("postOrder data:" + node.getData());

}

}

class TreeNode {

private int index;

private String data;

private TreeNode leftChild;

private TreeNode rightChild;

public TreeNode(int index, String data) {

this.index = index;

this.data = data;

}

public TreeNode getLeftChild() {

return leftChild;

}

public void setLeftChild(TreeNode leftChild) {

this.leftChild = leftChild;

}

public TreeNode getRightChild() {

return rightChild;

}

public void setRightChild(TreeNode rightChild) {

this.rightChild = rightChild;

}

public int getIndex() {

return index;

}

public void setIndex(int index) {

this.index = index;

}

public String getData() {

return data;

}

public void setData(String data) {

this.data = data;

}

}

}

傳入數(shù)組測(cè)試

public class test {

public static void main(String[] args) {

BinaryTree binaryTree=new BinaryTree();

String data[]={"A","B","C","D","E","#","F"};

ArrayListdatas=new ArrayList<>(Arrays.asList(data));

binaryTree.createBinerTree(datas.size(), datas);

binaryTree.preOrder(binaryTree.root);

}

}

結(jié)果

preOrder data:A

preOrder data:B

preOrder data:C

preOrder data:D

preOrder data:E

preOrder data:F

三、搜索二叉樹(shù)

二叉查找樹(shù)(又:二叉搜索樹(shù),二叉排序樹(shù)),它或者是一棵空樹(shù),或者是具有下列性質(zhì)的二叉樹(shù): 若它的左子樹(shù)不空,則左子樹(shù)上所有結(jié)點(diǎn)的值均小于它的根結(jié)點(diǎn)的值; 若它的右子樹(shù)不空,則右子樹(shù)上所有結(jié)點(diǎn)的值均大于它的根結(jié)點(diǎn)的值; 它的左、右子樹(shù)也分別為二叉排序樹(shù)。二叉排序樹(shù)的查找過(guò)程和次優(yōu)二叉樹(shù)類似,通常采取二叉鏈表作為二叉排序樹(shù)的存儲(chǔ)結(jié)構(gòu)中序遍歷二叉排序樹(shù)可得到一個(gè)關(guān)鍵字的有序序列,一個(gè)無(wú)序序列可以通過(guò)構(gòu)造一棵二叉排序樹(shù)變成一個(gè)有序序列,構(gòu)造樹(shù)的過(guò)程即為對(duì)無(wú)序序列進(jìn)行排序的過(guò)程。每次插入的新的結(jié)點(diǎn)都是二叉排序樹(shù)上新的葉子結(jié)點(diǎn),在進(jìn)行插入操作時(shí),不必移動(dòng)其它結(jié)點(diǎn),只需改動(dòng)某個(gè)結(jié)點(diǎn)的指針,由空變?yōu)榉强占纯?/p>

1、搜索二叉樹(shù)的實(shí)現(xiàn)

/**

* Author: Active_Loser

* Date: 2018/7/30 23:17

* Content: 實(shí)現(xiàn)搜索二叉樹(shù)的建立、添加、刪除等操作

*/

public class SearchBinryTree {

public TreeNode root;

public TreeNode put(int data) {

TreeNode node;

TreeNode parent = null;

if (root == null) {

node = new TreeNode(data);

root = node;

return node;

}

node = root;

while (node != null) {

parent = node;

if (data > parent.data) {

node = parent.rightChild;

} else if (data < parent.data) {

node = parent.leftChild;

} else {

return node;

}

}

node = new TreeNode(data);

if (data < parent.data) {

parent.leftChild = node;

node.parent = parent;

} else if (data > parent.data) {

parent.rightChild = node;

node.parent = parent;

}

return node;

}

public TreeNode search(int value) {

TreeNode node = root;

while (node != null && node.data != value) {

if (node.data > value) {

node = node.rightChild;

} else if (node.data < value) {

node = node.leftChild;

}

}

return node;

}

/**

* @param value 刪除的數(shù)值

* @return 返回刪除的節(jié)點(diǎn)

*/

public TreeNode delete(int value) {

//判斷是否包含需要?jiǎng)h除的數(shù)

TreeNode deleteNode = search(value);

if (null == deleteNode) {

return null;

}else {

delete(deleteNode);

}

}

private void delete(TreeNode node) {

if (node==null){

return null;

}

TreeNode parent=node.parent;

//做節(jié)點(diǎn)與有節(jié)點(diǎn)皆為NULL

if (node.leftChild==null&&node.rightChild==null){

if (parent.leftChild==node){

parent.leftChild=null;

}else {

parent.rightChild=null;

}

return;

}

//有左節(jié)點(diǎn)沒(méi)有右節(jié)點(diǎn)1.父節(jié)點(diǎn)的左節(jié)點(diǎn)2.父節(jié)點(diǎn)的右節(jié)點(diǎn)

if (node.leftChild!=null&&node.rightChild==null){

if (parent.leftChild==node){

parent.leftChild=node.leftChild;

}else if (parent.rightChild==node){

parent.rightChild=node.leftChild;

}

return;

}

//有右節(jié)點(diǎn)沒(méi)有左節(jié)點(diǎn)1.父節(jié)點(diǎn)的左節(jié)點(diǎn)2.父節(jié)點(diǎn)的右節(jié)點(diǎn)

if (node.leftChild!=null&&node.rightChild==null){

if (parent.leftChild==node){

parent.leftChild=node.rightChild;

}else if (parent.rightChild==node){

parent.rightChild=node.rightChild;

}

return;

}

//既有左節(jié)點(diǎn)也有右節(jié)點(diǎn)

//獲取刪除節(jié)點(diǎn)的后繼節(jié)點(diǎn)

TreeNode next=getNextNode(node);

delete(next);

node.data=next.data;

}

private TreeNode getNextNode(TreeNode node) {

if (node==null){

return null;

}else {

if (node.rightChild!=null){

return getMinTreeNode(node.rightChild);

}else {

TreeNode parent=node.parent;

while (parent!=null&&node==parent.rightChild){

node=parent;

parent=parent.parent;

}

return parent;

}

}

return null;

}

//右子樹(shù)最小值,左子樹(shù)最大值

public TreeNode getMinTreeNode(TreeNode node){

if (node==null){

return null;

}else {

while (node.leftChild !=null){

node=node.leftChild;

}

}

return node;

}

public void midOrder(TreeNode node) {

if (node == null) {

return;

} else {

midOrder(node.leftChild);

System.out.println("midOrder:" + node.data);

midOrder(node.rightChild);

}

}

class TreeNode {

private TreeNode leftChild;

private TreeNode rightChild;

private TreeNode parent;

private int data;

public TreeNode(int data) {

this.data = data;

}

public TreeNode getLeftChild() {

return leftChild;

}

public void setLeftChild(TreeNode leftChild) {

this.leftChild = leftChild;

}

public TreeNode getRightChild() {

return rightChild;

}

public void setRightChild(TreeNode rightChild) {

this.rightChild = rightChild;

}

public TreeNode getParent() {

return parent;

}

public void setParent(TreeNode parent) {

this.parent = parent;

}

public int getData() {

return data;

}

public void setData(int data) {

this.data = data;

}

}

}

總結(jié)

以上是生活随笔為你收集整理的java树算法_Java数据结构算法(三)树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。