目 錄
P28-4.1樹結構概述
順序存儲:開始位置、結束位置,插入數據、刪除數據=====》在數據量大的情況下,非常耗費時間!根據下標查找元素。
鏈表存儲:從第1個節點,開始往後找。。。【耗時!!!】
樹結構:查找性能、插入性能 較好!!!
雙親結點:雌雄同體!!!子節點的上一個節點。--------->子節點
路徑:從某個節點到達某個節點,途中經過的結點。
節點的度:節點有幾個子節點(子樹)。
節點的權:給節點賦予的值(節點中存儲的數值)。
葉子節點:沒有子節點的節點。
樹的高度:最大層數。【4】
森林:多個樹。
P29-4.2二叉樹的概述
二叉樹:任何一個節點的子節點數量不超過2!
二叉樹的子節點 分 左節點 和 右節點。
滿二叉樹:所有葉子節點都在最後一層,而且節點的總數爲 2^n-1。【n是樹的高度!】
滿二叉樹,是 完全二叉樹!
完全二叉樹:所有葉子節點都在最後一層或倒數第二層,且最後一層的葉子節點在左邊連續,倒數第二層的葉子節點在右邊連續。
從上到下,從左到右 依次 數能數完 就是 完全二叉樹!
P30-4.3創建二叉樹
雙鏈表 是 前驅 和 後繼,樹 是 左右孩子結點,不一樣!
二叉樹的5種形式:
P31-4.4遍歷二叉樹
遍歷詳解:https://blog.csdn.net/weixin_44949135/article/details/105291651
P32-4.5二叉樹中節點的查找
P33-4.6刪除二叉樹的子樹
刪除 節點(子樹):
- 無子節點(子節點一併刪除!);
- 有子節點。
1、BinaryTree.java
package demo5;
public class BinaryTree {
Node root;
// 設置根節點
public void setRoot(Node root) {
this.root = root;
}
// 獲取根節點
public Node getRoot() {
return root;
}
public void frontShow() {
if (root != null) {
root.frontShow();
}
}
public void midShow() {
if (root != null) {
root.midShow();
}
}
public void afterShow() {
if (root != null) {
root.afterShow();
}
}
public Node frontSearch(int i) {
return root.frontSearch(i);
}
public void delete(int i) {
if (root.value == i) {
root = null;
} else {
root.delete(i);
}
}
}
2、Node.java
package demo5;
public class Node {
// 節點的權
int value;
// 左兒子
Node leftNode;
// 右兒子
Node rightNode;
public Node(int value) {
this.value = value;
}
// 設置左兒子
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
// 設置右兒子
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
// 前序遍歷
public void frontShow() {
// 先遍歷當前節點的內容
System.out.print(value + "、");
// 左節點
if (leftNode != null) {
leftNode.frontShow();
}
// 右節點
if (rightNode != null) {
rightNode.frontShow();
}
}
// 中序遍歷
public void midShow() {
// 左子節點
if (leftNode != null) {
leftNode.midShow();
}
// 當前節點
System.out.print(value + "、");
// 右子節點
if (rightNode != null) {
rightNode.midShow();
}
}
// 後序遍歷
public void afterShow() {
// 左子節點
if (leftNode != null) {
leftNode.afterShow();
}
// 右子節點
if (rightNode != null) {
rightNode.afterShow();
}
// 當前節點
System.out.print(value + "、");
}
// 前序查找
public Node frontSearch(int i) {
Node target = null;
// 對比當前節點的值
if (this.value == i) {
return this;
// 當前節點的值不是要查找的節點
} else {
// 查找左兒子
if (leftNode != null) {
// 有可能可以查到,也可以查不到,查不到的話,target還是一個null
target = leftNode.frontSearch(i);
}
// 如果不爲空,說明在左兒子中已經找到
if (target != null) {
return target;
}
// 查找右兒子
if (rightNode != null) {
target = rightNode.frontSearch(i);
}
}
return target;
}
// 刪除一個子樹
public void delete(int i) {
Node parent = this;
// 判斷左兒子
if (parent.leftNode != null && parent.leftNode.value == i) {
parent.leftNode = null;
return;
}
// 判斷右兒子
if (parent.rightNode != null && parent.rightNode.value == i) {
parent.rightNode = null;
return;
}
// 遞歸檢查並刪除左兒子
parent = leftNode;
if (parent != null) {
parent.delete(i);
}
// 遞歸檢查並刪除右兒子
parent = rightNode;
if (parent != null) {
parent.delete(i);
}
}
}
3、TestBinaryTree.java
package demo5;
public class TestBinaryTree {
public static void main(String[] args) {
// 創建一顆樹
BinaryTree binTree = new BinaryTree();
// 創建一個根節點
Node root = new Node(1);
// 把根節點賦給樹
binTree.setRoot(root);
// 創建一個左節點
Node rootL = new Node(2);
// 把新創建的節點設置爲根節點的子節點
root.setLeftNode(rootL);
// 創建一個右節點
Node rootR = new Node(3);
// 把新創建的節點設置爲根節點的子節點
root.setRightNode(rootR);
// 爲第二層的左節點創建兩個子節點
rootL.setLeftNode(new Node(4));
rootL.setRightNode(new Node(5));
// 爲第二層的右節點創建兩個子節點
rootR.setLeftNode(new Node(6));
rootR.setRightNode(new Node(7));
// 前序遍歷樹
System.out.println("========前序遍歷樹========");
binTree.frontShow();
System.out.println("\n");
// 中序遍歷
System.out.println("========中序遍歷樹========");
binTree.midShow();
System.out.println("\n");
// 後序遍歷
System.out.println("========後序遍歷樹========");
binTree.afterShow();
System.out.println("\n\n");
// 前序查找
Node result = binTree.frontSearch(3);
System.out.println(result);
System.out.println(result == rootR);
System.out.println("\n\n===============");
// 刪除一個子樹
binTree.delete(4);
binTree.frontShow();
}
}
希望對您有所幫助~