二叉树的增删改查

首先建立Node

ublic class Node<T extends Comparable<T>> {
  private T date;
  private int index;
  private Node<T> lchile;
  private Node<T> rchile;
  
  public Node(){
	  
  }
  public Node(T date) {
	  this.date =date;
  }
  public Node(T date,Node<T> lNode,Node<T> rNode) {
    this.date =date;
    this.lchile =lNode;
    this.rchile =rNode;
  }
  
  
	public T getDate() {
		return date;
	}
	public void setDate(T date) {
		this.date = date;
	}
	public int getIndex() {
		return index;
	}
	public void setIndex(int index) {
		this.index = index;
	}
	public Node<T> getLchile() {
		return lchile;
	}
	public void setLchile(Node<T> lchile) {
		this.lchile = lchile;
	}
	public Node<T> getrNode() {
		return rchile;
	}
	public void setrNode(Node<T> rchile) {
		this.rchile = rchile;
	}
	@Override
	public String toString() {
		return "Node [date=" + date + ", index=" + index + ", lchile=" + lchile + ", rchile=" + rchile + "]";
	}
     }

增加很好写:以前的博客里有可以借鉴

 public void add(Node<T> node,T date){
		if (node ==null) {
		System.out.println("头结点为空");
		}else {
			if (node.date.compareTo(date) == -1) {
				if (node.rchile !=null) {
					 add(node.rchile, date);
				}else {
					Node<T> node2 =new Node<>(date);
					node.rchile =node2;
				}
			}else {
				  if (node.lchile !=null) {
						 add(node.lchile, date);
					}else {
						Node<T> node2 =new Node<>(date);
						node.lchile =node2;
					}
			}
			
		}
		 
	}

查找:特定值可以使用递归 如果要查找的值比 头结点的值大 就向右查找,否则向左查找

 public Node<T> Search(Node<T> node,T date) {
		
			if (node.date.compareTo(date) == -1 && node.rchile!=null ) {			
				return Search(node.rchile, date);
			}else if (node.date.compareTo(date) == 1 && node.lchile !=null) {
				
				return Search(node.lchile, date);
			}else{				
				return node;
			}
		}

删除:删除分为三种情况:请看
  第一种:如果为叶子结点,则可以直接删除,如图一。



  第二种:如果只有左子树或者只有右子树的时候,只要令其左子树或右子树为其父节点的左子树或右子树即可,如图二。


  


  第三种:如果节点既有左节点,又有右节点,则我们需要先用中序序列中节点的前驱或后序替换该节点,然后删除其前驱或后序节点。此时该节点的前驱或后序节点必然是没有右孩子或者左孩子的节点,删除方法可以参照第二种,如图三。


  

 代码:

	 public boolean Delete(Node<T> root,T date){
	        //引用当前节点,从根节点开始
	        Node curr = root;
	        //应用当前节点的父节点
	        Node parentNode = root;
	        //是否为左节点
	        boolean isLeftChild = true;
	        //进行比较,查找是否存在要删除的节点
	        while(curr.date.compareTo(date)!=0){
	            parentNode = curr;
	            if(curr.date.compareTo(date)==1){
	                curr = curr.lchile;
	                isLeftChild = true;
	            }else {
	                curr = curr.rchile;
	                isLeftChild = false;
	            }
	            //如果查找不到
	            if(curr == null) {
	                return false;
	            }
	        }
	        //刪除叶子节点
	        if(curr.lchile == null && curr.rchile == null){
	            if(curr == root) {
	                root = null;
	            } else if(isLeftChild) {
	                parentNode.lchile = null;
	            } else {
	                parentNode.rchile = null;
	            }
	        }else if(curr.lchile == null){//删除节点的左节点为空
	            if(curr == root){
	                root = root.rchile;
	            }else if(isLeftChild) {
	                parentNode.lchile = curr.rchile;
	            }else {
	                parentNode.rchile = curr.rchile;
	            }
	        }else if (curr.rchile == null) {//删除节点的右节点为空
	            if(curr == root){
	                root = root.lchile;
	            }else if(isLeftChild) {
	                parentNode.lchile = curr.lchile;
	            }else {
	                parentNode.rchile = curr.lchile;
	            }
	        }else {//如果要删除的节点有左右两个子节点
	            Node successor = getSuccessor(curr);
	            if(curr == root){
	                root = successor;
	            }else if(isLeftChild){
	                parentNode.lchile = successor;
	            }else {
	                parentNode.rchile = successor;
	            }
	            successor.lchile = curr.lchile;
	        }
	        return true;
	    }
	  public Node getSuccessor(Node delNode) {//获取要删除节点的后边的点
	        Node successor = delNode;
	        Node successorParent = delNode;
	        Node curr = delNode.rchile;
	        while(curr != null){
	            successorParent = successor;
	            successor = curr;
	            curr = curr.lchile;
	        }
	        if(successor != delNode.rchile){
	            successorParent.lchile = successor.rchile;
	            successor.rchile = delNode.rchile;
	        }
	        return successor;
	    }

修改 就是先删除之后 在添加。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AVL树是一种自平衡的二叉搜索树,可以高效地执行增删改查操作。下面以C语言为例来介绍AVL树的增删改查操作。 首先,我们需要定义AVL树节点的数据结构,包括节点的值、左子树指针、右子树指针和节点的高度。 ```c typedef struct AVLNode { int val; struct AVLNode* left; struct AVLNode* right; int height; } AVLNode; ``` 接下来,我们可以实现AVL树的插入、删除、更新和查询操作。 1. 插入操作: 插入节点的基本流程是先按照二叉搜索树的规则找到插入位置,然后更新节点的高度,并进行平衡操作,使树保持平衡。 ```c AVLNode* insert(AVLNode* root, int val) { if (root == NULL) { root = createNode(val); } else if (val < root->val) { root->left = insert(root->left, val); } else if (val > root->val) { root->right = insert(root->right, val); } root->height = max(height(root->left), height(root->right)) + 1; int balance = getBalance(root); if (balance > 1 && val < root->left->val) { return rightRotate(root); } if (balance < -1 && val > root->right->val) { return leftRotate(root); } if (balance > 1 && val > root->left->val) { root->left = leftRotate(root->left); return rightRotate(root); } if (balance < -1 && val < root->right->val) { root->right = rightRotate(root->right); return leftRotate(root); } return root; } ``` 2. 删除操作: 删除节点的基本流程是先按照二叉搜索树的规则找到待删除节点,然后更新节点的高度,并进行平衡操作,使树保持平衡。 ```c AVLNode* delete(AVLNode* root, int val) { if (root == NULL) { return root; } else if (val < root->val) { root->left = delete(root->left, val); } else if (val > root->val) { root->right = delete(root->right, val); } else { if (root->left == NULL || root->right == NULL) { AVLNode* temp = root->left ? root->left : root->right; if (temp == NULL) { temp = root; root = NULL; } else { *root = *temp; } free(temp); } else { AVLNode* temp = minValueNode(root->right); root->val = temp->val; root->right = delete(root->right, temp->val); } } if (root == NULL) { return root; } root->height = max(height(root->left), height(root->right)) + 1; int balance = getBalance(root); if (balance > 1 && getBalance(root->left) >= 0) { return rightRotate(root); } if (balance < -1 && getBalance(root->right) <= 0) { return leftRotate(root); } if (balance > 1 && getBalance(root->left) < 0) { root->left = leftRotate(root->left); return rightRotate(root); } if (balance < -1 && getBalance(root->right) > 0) { root->right = rightRotate(root->right); return leftRotate(root); } return root; } ``` 3. 更新操作: 更新操作即是先删除旧节点,然后插入新节点。 ```c AVLNode* update(AVLNode* root, int oldVal, int newVal) { root = delete(root, oldVal); root = insert(root, newVal); return root; } ``` 4. 查询操作: 查询操作即是在树中按照二叉搜索树的规则查找目标值。 ```c AVLNode* search(AVLNode* root, int val) { if (root == NULL || root->val == val) { return root; } else if (val < root->val) { return search(root->left, val); } else { return search(root->right, val); } } ``` 以上就是使用C语言实现AVL树的插入、删除、更新和查询操作的示例代码,希望对你有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值