Data Structure-Binary Search Tree (BST)

binary search tree

Insert image description here

These rules need to be met:

  • The left child node is smaller than the parent node
  • The right child node is greater than the parent node

Note: Any value on the left side of BST will not be greater than the one on the right side.

Search efficiency

Very good. Every time, the other half of the branches can be discarded according to the size, which greatly reduces the number of comparisons.

The specific performance depends on the number of layers and balance of the tree.
Insert image description here

Nodes of BST tree

struct Node
{
    
    
	Node* parent;
	Node* left;
	Node* right;
	int val;
}

Insertion of BST

bool Insert(Node* root,Node* newNode)
{
    
    
	Node* head =nullptr;
	if(root==nullptr)
	{
    
    
		*root = *newNode;
		return true;
	}
	
	Node* current = root;
	while(current!=nullptr)
	{
    
    
		if(newNode->val==current->val) return nullptr;
		else if(newNode->val>current->val) 
		{
    
    
			if(current->right==nullptr)
			{
    
    
				current->right = newNode;
				newNode->parent = current;
			}
			current = current->right;
		}
		else if(newNode->val<current->val)
		{
    
    
			if(current->left==nullptr)
			{
    
    
				current->left = newNode;
				newNode->parent = current;
			}
			current = current->left;
		}
	}
	return head;
}

BST lookup

Node* Search(Node* root, int target)
{
    
    
    Node* current = root;
    while (current != nullptr)
    {
    
    
        if (target == current->val)
        {
    
    
            return current; // 找到目标节点,返回它
        }
        else if (target < current->val)
        {
    
    
            current = current->left; // 目标值较小,向左子树查找
        }
        else
        {
    
    
            current = current->right; // 目标值较大,向右子树查找
        }
    }
    return nullptr; // 未找到目标节点
}

BST delete

Deleting BST is more complicated and you need to understand the traversal order of the binary tree first
《Binary Tree》

Insert image description here
The predecessor and successor of the binary tree are calculated according to in-order traversal, L is called the predecessor, and R is the successor.
Insert image description here

  1. If a tree has no child nodes, delete them directly
  2. If a tree has only one child node, delete the current node and add the child node to this position
  3. If there are two child nodes, the operation is complicated, perform the following operations
    • Find the maximum left subtree or minimum right subtree of the deleted node
    • We select the right smallest or the left largest
    • We connect the subtree of the selected node to the parent node of the selected node
    • Replace the selected node with the deleted node and hold the left and right subtrees of the deleted node
//查找子树最大值
Node* FindMax(Node* node)
{
    
    
	Node* current = node;
	while(current!=nullptr)
	{
    
    
		current = current->right;
	}
	return current;
}
Node* FindMin(Node* node)
{
    
    
	Node* current = node;
	while(current!=nullptr)
	{
    
    
		current = current->left;
	}
	return current;
}

//需要先搜索找出被删除节点的指针
Node* DeleteNode(Node* root,Node* target)
{
    
    
	//删除根节点,返回空指针
	if(root==target)
	{
    
    
		return nullptr;
	}
	//子节点不存在,将当前节点从父节点上移除
	if(target->left==nullptr&&target->right==nullptr)
	{
    
    
		target->parent = nullptr;
	}
	//一个子节点为空,左子节点为空
	else if(target->left==nullptr)
	{
    
    
		if(target==target->parent->left)
		{
    
    
			target->parent->left = target->right;
			target->right->parent = target->parent; 
		}
		else
		{
    
    
			target->parent->right = target->right;
			target->right->parent = target->parent;
		}
	}
	else if(target->right==nullptr)
	{
    
    
		if(target==target->parent->right)
		{
    
    
			target->parent->right = target->left;
			target->left->parent = target->parent;
		}
		else
		{
    
    
			target->parent->left = target->left;
			target->left->parent = target->parent;
		}
	}
	//两个子节点存在
	else
	{
    
    
		//左侧最大,右侧最小值
		Node* min = FindMin(target->right);
		//选中的节点的子树连接在选中的节点的父节点
		min->parent->left = min->left;
		min->left->parent = min->parent;
		min->parent->right= min->right;
		min->right->parent = min->parent;
		//选中节点置换删除节点
		if(target->parent->left==target) 
		{
    
    
			target->parent->left=min;
			min->parent = target->parent;
		}
		else 
		{
    
    
			target->parent->right = min;
			min->parent = target->parent;
		}
		//选中节点继承被删除节点的子树
		min->left = target->left;
		target->left->parent = min;
		min->right = target->right;
		target->right->parent = min;
		
	}
	
}

Subtrees and identical trees

If implemented recursively, there may be a risk of stack explosion, but generally speaking, the average depth of BST will not cause this problem and can be used. The non-recursive implementation is no longer given here

bool isSubtree(TreeNode* s, TreeNode* t) {
    
    
    if (!s) return false; // 父树为空,不可能有子树
    if (isSameTree(s, t)) return true; // 当前子树和子树t相同
    return isSubtree(s->left, t) || isSubtree(s->right, t); // 继续递归检查左右子树
}

bool isSameTree(TreeNode* p, TreeNode* q) {
    
    
    if (!p && !q) return true; // 两棵树都为空
    if (!p || !q) return false; // 一棵树为空,另一棵不为空
    return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}

BST has a very serious problem, that is, extreme situations may occur. In this case, BST will degenerate into a double linked list, resulting in the loss of search advantages.
Insert image description here

Guess you like

Origin blog.csdn.net/qq_46273241/article/details/133421106