什么是二叉树
- 在进行链表结构开发的过程中会发现所有的数据按照首尾相连的状态进行保存,那么当要进行某一个数据进行查询的时候,这种情况下所面对的时间复杂度是"n",如果说她的数据量现在比较少(不超过30个),那么在性能上是不会有太大差别的,而一袋保存的数据量很大,这个时候时间复杂度就会严重损耗程序的性能,那么现在对于数据存储结构就必须发生改变,应该可以尽可能的减少检索次数为出发点进行设计,对于现在的数据结构而言,最好的性能就是"o(logn)",所以要想实现它就可以利用二叉树的结构来完成.
- 如果要想实现实现一棵树结构的定义,那么就需要去考虑数据的存储形式,在二叉树的实现原理之中其基本的实现原理如下:取第一个数据为根节点,当比根节点小的数据要放在树的左子树,而大于节点的数据要放在该节点的右子树
代码
- 接下来就是代码了,实体类
class Person implements Comparable<Person>{
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person per) {
return per.age - this.age;
}
}
- 二叉树排序的相关代码
class BinaryTree<T extends Comparable<T>>{
//节点类
private class Node{
private Comparable<T> data;
private Node parent;
private Node left;
private Node right;
public Node(Comparable<T> data){
this.data = data;
}
//添加节点
public void add(Node newNode){
if(this.data.compareTo((T) newNode.data) <= 0){
if(this.left == null){
this.left = newNode;
newNode.parent = this;
}else{
this.left.add(newNode);
}
}else{
if(this.right == null){
this.right = newNode;
newNode.parent = this;
}else{
this.right.add(newNode);
}
}
}
//遍历节点(中序遍历)先序(根->左->右),中序(左->根->右),后序(左->右->根)
public void toarry(){
if(this.left != null){
this.left.toarry();
}
BinaryTree.this.returnData[BinaryTree.this.foot++] = this.data;
if(this.right != null){
this.right.toarry();
}
}
//删除节点
public void remove(Node removeNode){
if(removeNode.left == null && removeNode.right == null){//没有任何的子节点,但是父节点的右边有节点
if(removeNode.parent.right == removeNode){
removeNode.parent.right = null;
}else if(removeNode.parent.left == removeNode){
removeNode.parent.left = null;
}
}else if(removeNode.left != null && removeNode.right == null){//只有一个左节点
removeNode.parent.left = removeNode.left;
removeNode.left.parent = removeNode.parent;
}else if(removeNode.left == null && removeNode.right != null){//只有一个右节点
removeNode.parent.left = removeNode.right;
removeNode.right.parent = removeNode.parent;
}else{//两边都有节点,则将右边节点中最左边的节点找到,改变其引用
Node moveNode = removeNode.right;
while (moveNode.left != null){
moveNode = moveNode.left;
}
//如果是根节点
if(BinaryTree.this.root == removeNode){
if(BinaryTree.this.root.right == moveNode){
moveNode.right = moveNode.right;
}else{
moveNode.parent.left = null;
}
moveNode.left = BinaryTree.this.root.left;
BinaryTree.this.root = moveNode;
}else{
if(removeNode.parent.left == removeNode){
removeNode.parent.left = moveNode;
moveNode.parent.left = null;
if(moveNode.right != null){
moveNode.parent.left = moveNode.right;
moveNode.right.parent = moveNode.parent;
}
moveNode.parent = removeNode.parent;
moveNode.right = removeNode.right;
moveNode.left = removeNode.left;
}
}
}
}
//判断节点是否存在
public Node containsNode(Node node){
if(this.data.compareTo((T) node.data) == 0){
return this;
}else if(this.data.compareTo((T) node.data) < 0){
if(this.left != null){
return this.left.containsNode(node);
}else{
return null;
}
}else {
if(this.right != null){
return this.right.containsNode(node);
}else{
return null;
}
}
}
}
//==========分割线==========
private Node root;
private int count = 0;
private int foot = 0;
private Object[] returnData;
//添加节点
public void add(Comparable<T> data){
Node newNode = new Node(data);
if(this.root == null){
this.root = newNode;
}else{
this.root.add(newNode);
}
this.count++;
}
//遍历节点
public Object[] toarry(){
if(this.count == 0){
return null;
}
this.foot = 0;
this.returnData = new Object[count];
this.root.toarry();
return this.returnData;
}
//删除节点
public void remove(Comparable<T> data){
if(data != null){
Node newNode = new Node(data);
newNode = this.root.containsNode(newNode);
if(newNode != null){
this.root.remove(newNode);
this.count--;
}
}
}
}
- 主函数
public class BinaryDemo {
public static void main(String[] args) {
BinaryTree<Person> tree = new BinaryTree<Person>();
tree.add(new Person("小强-80", 80));
tree.add(new Person("小强-60", 60));
tree.add(new Person("小强-90", 90));
tree.add(new Person("小强-75", 75));
tree.add(new Person("小强-73", 73));
tree.add(new Person("小强-74", 74));
tree.add(new Person("小强-76", 76));
tree.add(new Person("小强-50", 50));
tree.add(new Person("小强-10", 10));
tree.add(new Person("小强-100", 100));
tree.add(new Person("小强-102", 102));
tree.add(new Person("小强-95", 95));
tree.add(new Person("小强-99", 99));
tree.add(new Person("小强-94", 94));
tree.remove(new Person("小强-80", 80));
System.out.println(Arrays.toString(tree.toarry()));
}
}
删除操作逻辑
其实最想说的是删除操作,因为删除操作还是挺非逻辑的,一共分为三种情况
- 情况一:删除的节点底下没有任何的节点
- 情况二:删除的节点有一个节点,左子树 或者右子树
- 情况三:删除的节点下有若干分支,在这种情况下是拿删除节点的第一个右子树的最左边的左子树,如下图