数据结构
树
简单二叉树
树包括 左子右子树:节点 key value值
添加元素
给指定节点x添加元素
若头节点为空,则最先给头节点赋值,若头节点不为空 ,则进行key与x.key比较 若大于 则向右递归添加 若x.left 或者x.right =null 则让 x.left 或者x.right = put(x.right,key,value)
查找
在指定节点中查找 若key>x.key则向右插 若小于向左查,若等于 则返回value 若没有 返回null
删除
在指定节点中进行查找,若key>x.key则向右查,若key<x.key向左查,
若等于 则删除该节点
- 若左子树不存在,则让他的右子树,
- 若右子树不存在,则返回他的左子树
- 若左右子树都存在的情况下,n-- ;建一个minNode,minNode:右子树的最左节点,删除最左节点,将x的左右子节点赋给minNode的左右子节点,让 将minNode的值赋给x;
package com.AGui.tree;
public class BinaryTree<Key extends Comparable<Key>, Value> {
//根节点
private Node root;
//记录元素个数
private int N;
private class Node {
public Key key;
public Value value;
//记录左子节点
public Node left;
// 记录右子节点
public Node right;
public Node(Key key, Value value, Node left, Node right) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
}
}
// 获取树中元素个数
public int size() {
return N;
}
//向树中添加元素值
public void put(Key key, Value value) {
root = put(root, key, value);
}
//向指定树x中插入key value 返回添加元素后的树
public Node put(Node x, Key key, Value value) {
//如果x为空
if (x == null) {
N++;
return new Node(key, value, null, null);
}
// 如果x不为空 比较key 若key大于x.key
int i = key.compareTo(x.key);
if (i > 0) {
// 若大于则向右继续找
x.right = put(x.right, key, value);
}
// 若小于则向左继续找
else if (i < 0) {
x.left = put(x.left, key, value);
}
// 若等于替换value值
else {
x.value = value;
}
return x;
}
//查找树中key对应的value的值
public Value get(Key key) {
return get(root, key);
}
//查找指定树中的值
public Value get(Node x, Key key) {
//若该树为null 则返回null
if (x == null) {
return null;
}
int i = key.compareTo(x.key);
//若该树不为null,若key大于x.key向右找 若小于 想左找 若等于 取出
if (i > 0) {
return get(x.right, key);
} else if (i < 0) {
return get(x.left, key);
} else
return x.value;
}
//删除树中的key
public void delete(Key key) {
root = delete(root, key);
}
//删除指定树中的key
public Node delete(Node x, Key key) {
//如果x为null 返回null
if (x == null)
return null;
//x不为null key和x.key进行大小比较
int i = key.compareTo(x.key);
//大于 向右子树进行递归
if (i > 0) {
x.right = delete(x.right, key);
}
// 小于 向左子树进行递归
if (i < 0) {
x.left = delete(x.left, key);
}
// 等于
else {
//个数减一
N--;
//新节点的key等于当前节点的key 意思就是删除当前节点
//1.1如果当前节点的左子树不存在
if (x.left == null) {
return x.right;
// 1.2如果当前结点的右子树不存在
}
if (x.right == null) {
return x.left;
}
// 若左右子树都存在
// 找到替换的节点进行替换 替换节点:右子树的最左边的节点
else {
Node minNode = x.right;
while (minNode.left != null) {
minNode = minNode.left;
}
//删除右子树最小节点
Node n = x.right;
if (n.left != null) {
if (n.left.left == null) {
n.left = null;
} else {
n = n.left;
}
}
//将minNode替换到被删除的节点位置
minNode.left = x.left;
minNode.right = x.right;
x = minNode;
}
}
return x;
}
//查找最小键
public Key min() {
return min(root).key;
}
public Node min(Node x) {
if (x.left != null) {
return min(x.left);
} else {
return x;
}
}
//查找最大键
public Key max() {
return max(root).key;
}
public Node max(Node x) {
if (x.right != null) {
return max(x.right);
} else return x;
}
}
二叉树的先序遍历
//获取整个树的所有的键
public List<Key> preErgodic(){
LinkedList<Key> keys = new LinkedList<>();
preErgodic(root,keys);
return keys;
}
//获取指定树中所有的键
private void preErgodic(Node x, Queue<Key> keys){
if (x==null){
return;
}
keys.add(x.key);
if(x.left!=null){
preErgodic(x.left,keys);
}if(x.right!=null){
preErgodic(x.right,keys);
}
}
中序遍历
//获取所有树的中序遍历
public List<Key> midErgodic(){
LinkedList<Key> keys = new LinkedList<>();
midErgodic(root,keys);
return keys;
}
//获取指定树的中序遍历
private void midErgodic(Node x,List<Key> keys){
if(x==null){
return;
}
if(x.left!=null){
midErgodic(x.left,keys);
}
keys.add(x.key);
if(x.right!=null){
midErgodic(x.right,keys);
}
}
层序遍历
层序遍历:广度优先
首先将头节点放入节点队列,然后判断 ,若节点队列的长度为0 则说明所有已经便利完了
循环中:队列弹出一个节点,将其key加入到keys队列中,对该节点进行判断,若有左子节点,将左子节点加入到节点队列中,若有右子节点,将其加入到队列中,若没有 则进行下次循环
//层序遍历
public List<Key> layerErgodic(){
LinkedList<Node> node = new LinkedList<>();
LinkedList<Key> keys= new LinkedList<>();
//最先弹入根节点,判断有没有左子节点 若有 放入队列中,若没有判断有没有右子节点,若有 放在队列中
node.addFirst(root);
while (!node.isEmpty()){
//节点队列中弹出的节点 放入到keys中
Node n = node.remove();
keys.add(n.key);
if(n.left!=null){
node.add(n.left);
}
if(n.right!=null){
node.add(n.right);
}
}
return keys;
}
最大深度
//获取树的最大深度
public int maxDepth(){
return maxDepth(root);
}
//获取节点的最大深度
private int maxDepth(Node x){
int max = 0;
int maxLeft = 0;
int maxRight = 0;
if(x==null){
return 0;
}
if(x.left!=null){
maxLeft= maxDepth(x.left);
}
if(x.right!=null){
maxRight = maxDepth(x.right);
}
max= maxLeft>maxRight?maxLeft+1:maxRight+1;
return max;
}