Skip to content

Commit 38887f3

Browse files
committed
[Update]
1.Update the file directory.
1 parent 1a2740f commit 38887f3

File tree

7 files changed

+1538
-0
lines changed

7 files changed

+1538
-0
lines changed
File renamed without changes.

DataStructrue/Tree/BinaryTree.java

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
public class BinaryTree<K extends Comparable<K>, V> {
2+
protected class Node{
3+
protected Node left, right;
4+
protected K k;
5+
protected V v;
6+
protected Integer N;
7+
public Node(K k, V v, Integer n){this.k = k; this.v = v; this.N = n;}
8+
}
9+
10+
public Integer size(Node n){
11+
if(null == n) return 0;
12+
return n.N;
13+
}
14+
15+
protected Node root;
16+
private Node put(Node node, K k, V v){
17+
if(null == node) return new Node(k, v, 1);
18+
if(k.compareTo(node.k) < 0) node.left = put(node.left, k, v);
19+
else if(k.compareTo(node.k) > 0) node.right = put(node.right, k, v);
20+
else node.v = v;
21+
node.N = size(node.left) + size(node.right) + 1;
22+
return node;
23+
}
24+
public void put(K k, V v){
25+
root = put(root, k, v);
26+
}
27+
28+
private V get(Node node, K k){
29+
if(null == node) return null;
30+
if(k.compareTo(node.k) < 0) return get(node.left, k);
31+
else if (k.compareTo(node.k) > 0) return get(node.right, k);
32+
else return node.v;
33+
}
34+
public V get(K k){
35+
return get(root, k);
36+
}
37+
38+
public void deleteMin(){
39+
root = deleteMin(root);
40+
}
41+
42+
private Node deleteMin(Node node){
43+
if(null == node.left) return node.right;
44+
node.left = deleteMin(node.left);
45+
node.N = size(node.left) + size(node.right) - 1;
46+
return node;
47+
}
48+
49+
public Node min(Node n){
50+
if(n.left == null) return n;
51+
return min(n.left);
52+
}
53+
54+
private Node delete(Node n, K k){
55+
if(n == null) return null;
56+
int cmp = k.compareTo(n.k);
57+
if(cmp < 0) n.left = delete(n.left, k);//delete node is at left side of n
58+
else if(cmp > 0) n.right = delete(n.right, k);
59+
else{ //Current node is the node to be deleted
60+
if(n.right == null) return n.left;
61+
if(n.left == null) return n.right;
62+
Node temp = min(n.right); //temp will replace n to be the parent node.
63+
temp.left = n.left;
64+
temp.right = deleteMin(n.right);
65+
n = temp;
66+
}
67+
return n;
68+
}
69+
public void delete(K k){
70+
root = delete(root, k);
71+
}
72+
73+
74+
/**
75+
* @Description: 前序遍历,访问当前节点,继而访问左结点,最后访问右结点
76+
* @param n
77+
*/
78+
private void preOrderTraversal(Node n){
79+
if(n != null) System.out.println(n.v);
80+
if(n.left != null) preOrderTraversal(n.left);
81+
if(n.right != null) preOrderTraversal(n.right);
82+
}
83+
84+
public void preOrderTraversal(){
85+
preOrderTraversal(root);
86+
}
87+
88+
/**
89+
* @Description: 中序遍历,先访问左结点,后访问当前节点,最后访问右结点。
90+
* @param n
91+
*/
92+
private void inOrderTraversal(Node n){
93+
if(n != null && n.left != null) inOrderTraversal(n.left);
94+
if(null != n) System.out.println(n.v);
95+
if(n != null && n.right != null) inOrderTraversal(n.right);
96+
}
97+
98+
public void inOrderTraversal(){
99+
inOrderTraversal(root);
100+
}
101+
102+
/**
103+
* @Description: 右序遍历,先访问左结点,后访问右结点,最后访问当前节点
104+
* @param n
105+
*/
106+
private void postOrderTraversal(Node n){
107+
if(n != null && n.left != null) postOrderTraversal(n.left);
108+
if(n != null && n.right != null) postOrderTraversal(n.right);
109+
if(n != null) System.out.println(n.v);
110+
}
111+
112+
public void postOrderTraversal(){
113+
postOrderTraversal(root);
114+
}
115+
116+
public static void main(String[] args) {
117+
BinaryTree<Integer, Integer> binaryTree = new BinaryTree<>();
118+
binaryTree.put(11, 11);
119+
binaryTree.put(8, 8);
120+
binaryTree.put(16, 16);
121+
binaryTree.put(4, 4);
122+
binaryTree.put(9, 9);
123+
binaryTree.put(14, 14);
124+
binaryTree.put(18, 18);
125+
binaryTree.preOrderTraversal();
126+
System.out.println("=====================");
127+
binaryTree.inOrderTraversal();
128+
System.out.println("=====================");
129+
binaryTree.postOrderTraversal();
130+
}
131+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
public class CompleteBinaryTree<K extends Comparable<K>> {
2+
private Object[] arr; //因为无法实现泛型数组,我们通过Object数组替代。第一个位置不存储元素
3+
private int N; //树中元素的个数。
4+
public CompleteBinaryTree(int N) {
5+
arr = new Object[N];
6+
}
7+
private void swap(int i, int j){ //交换两个元素的位置
8+
Object temp = arr[i];
9+
arr[i] = arr[j];
10+
arr[j] = temp;
11+
}
12+
@SuppressWarnings("unchecked")
13+
private boolean less(Integer i, Integer j){
14+
return ((K)arr[i]).compareTo(((K)arr[j])) < 0;
15+
}
16+
private void swin(int k){
17+
while(k > 1 && less(k/2, k)){
18+
swap(k/2, k);
19+
k /= 2;
20+
}
21+
}
22+
public void insert(K k){
23+
arr[++N] = k;
24+
swin(N);
25+
}
26+
public Integer size(){
27+
return N;
28+
}
29+
@SuppressWarnings("unchecked")
30+
public K get(int i){
31+
return (K)arr[i];
32+
}
33+
private void sink(int i){
34+
while(i * 2 <= N){
35+
int j = i * 2;
36+
if(j + 1 < N && less(j, j+1)) j++; //取两个子结点中更大的一个。
37+
swap(i, j);
38+
i = j; //在当前子树中继续进行下沉
39+
}
40+
}
41+
42+
public K delMax(){
43+
K max = (K)arr[1];
44+
swap(1, N + 1);
45+
arr[N + 1] = null;
46+
sink(1);
47+
N--;
48+
return max;
49+
}
50+
51+
public static void main(String[] args) {
52+
CompleteBinaryTree<Integer> cbtree = new CompleteBinaryTree<>(100);
53+
cbtree.insert(1);
54+
cbtree.insert(2);
55+
cbtree.insert(3);
56+
cbtree.insert(4);
57+
cbtree.insert(5);
58+
cbtree.insert(6);
59+
cbtree.delMax();
60+
for(int i = 1; i <= cbtree.size(); i++){
61+
System.out.println(cbtree.get(i));
62+
}
63+
}
64+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# 完全二叉树 Complete Binary Tree
2+
* ****就是通过完全二叉树实现的,可以参考排序部分的堆排序。
3+
>当一一棵二叉树的每个结点都大于等于它的两个子结点时,被称为**堆有序**
4+
5+
>完全二叉树是效率很高的数据结构,堆是一种完全二叉树或者近似完全二叉树,所以效率极高,像十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能优化,几乎每次都要考到的二叉排序树的效率也要借助平衡性来提高,而平衡性基于完全二叉树。
6+
7+
## 判断完全二叉树
8+
>若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
9+
10+
![CompleteBinaryTree](https://i.imgur.com/YzCQuXP.jpg)
11+
* 对于第n行,最多有2^(n-1)个元素。
12+
13+
## 二叉堆的实现方式
14+
* 通过数组实现二叉堆
15+
```Java
16+
public class CompleteBinaryTree<K extends Comparable<K>> {
17+
private Object[] arr; //因为无法实现泛型数组,我们通过Object数组替代。第一个位置不存储元素
18+
private int N; //树中元素的个数。
19+
public CompleteBinaryTree(int N) {
20+
arr = new Object[N];
21+
}
22+
private void swap(int i, int j){ //交换两个元素的位置
23+
Object temp = arr[i];
24+
arr[i] = arr[j];
25+
arr[j] = temp;
26+
}
27+
@SuppressWarnings("unchecked")
28+
private boolean less(Integer i, Integer j){
29+
return ((K)arr[i]).compareTo(((K)arr[j])) < 0;
30+
}
31+
//上浮方法
32+
private void swin(int k){
33+
//当前节点不是第一个元素并且大于它的父结点,则进行位置的交换。
34+
while(k > 1 && less(k/2, k)){
35+
swap(k/2, k);
36+
k /= 2;
37+
}
38+
}
39+
public Integer size(){
40+
return N;
41+
}
42+
@SuppressWarnings("unchecked")
43+
public K get(int i){
44+
return (K)arr[i];
45+
}
46+
private void sink(int i){
47+
while(i * 2 <= N){
48+
int j = i * 2;
49+
if(j + 1 < N && less(j, j+1)) j++; //取两个子结点中更大的一个。
50+
swap(i, j);
51+
i = j; //在当前子树中继续进行下沉
52+
}
53+
}
54+
}
55+
```
56+
57+
## 完全二叉树的增删改查
58+
*
59+
```Java
60+
public void insert(K k){
61+
arr[++N] = k;
62+
swin(N);
63+
}
64+
```
65+
66+
*
67+
```Java
68+
public K delMax(){
69+
K max = (K)arr[1];
70+
swap(1, N + 1);
71+
arr[N + 1] = null;
72+
sink(1);
73+
N--;
74+
return max;
75+
}
76+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# 平衡二叉树Balanced Binary Tree
2+
>平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树。平衡二叉树要求对于每一个节点来说,它的左右子树的高度之差不能超过1,如果插入或者删除一个节点使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。
3+
4+
## 定义
5+
>平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉树:**它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1**,且它的左子树和右子树都是一颗平衡二叉树。
6+
7+
* 旋转
8+
>通过对树进行简单的修复来让其重新恢复到平衡,而这样的简单操作我们就称之为旋转,当然旋转也有单旋转和双旋转之分。
9+
假设结点X是失衡点,它必须重新恢复平衡,由于任意结点的孩子结点最多有两个,而且导致失衡的必要条件是X结点的两棵子树高度差为2(大于1),因此一般只有以下4种情况可能导致X点失去平衡:
10+
① 在结点X的左孩子结点的左子树中插入元素
11+
② 在结点X的左孩子结点的右子树中插入元素
12+
③ 在结点X的右孩子结点的左子树中插入元素
13+
④ 在结点X的右孩子结点的右子树中插入元素
14+
15+
* 高度
16+
>高度是指当前结点到叶子结点的最长路径,如所有叶子结点的高度都为0。
17+
![height](https://i.imgur.com/dA8OWAs.png)
18+
19+
* 左左单旋转(LL)情景①分析
20+
![LL](https://i.imgur.com/kpMVlUs.png)
21+
```Java
22+
private AVLNode singleRotateLeft(AVLNode n){
23+
AVLNode left1 = n.left;
24+
n.left = left1.right;
25+
left1.right = n;
26+
left1.height = Math.max(left1.left.height, left1.right.height) + 1;
27+
n.height = Math.max(n.left.height, n.right.height) + 1;
28+
return left1;
29+
}
30+
```
31+
32+
* 右右单旋转(RR)情景④分析
33+
![RR](https://i.imgur.com/CkFlj4X.png)
34+
```Java
35+
private AVLNode singleRotateRight(AVLNode n){
36+
AVLNode right1 = n.right;
37+
n.left = right1.left;
38+
right1.left = n;
39+
right1.height = Math.max(right1.left.height, right1.right.height) + 1;
40+
n.height = Math.max(n.left.height, n.right.height) + 1;
41+
return right1;
42+
}
43+
```
44+
45+
* 平衡二叉树的双旋转算法与实现
46+
* 左右双旋转(LR)情景②分析
47+
![LR](https://i.imgur.com/926XxBS.png)

0 commit comments

Comments
 (0)