Part 2-- tree data structure of the binary sort (search, search) tree

Binary sort tree

Introduced

Basic properties:

Binary sort tree (also known as binary search, search tree)

  1. If the left subtree is not empty, then the value of the left sub-tree, all the nodes are less than the value of the root;
  2. If the right subtree is not empty, then the right sub-tree nodes are all values greater than the value of the root;
  3. Left and right subtrees are also binary sort tree.
  4. Key does not allow the same node.

Binary search and binary sort tree

Also known as binary search binary search requires the original linear form ordered, it is a very efficient search method. If required frequent changes in the table using a binary search, its efficiency is very low because of the low efficiency of the modification operation sequence table. If you only consider the frequent changes, we can use the list. However, the list of search efficiency and very low. The comprehensive advantages of these two data structures, binary search tree (Binary Sort / Search Tree) was born.

Given number string \ ((65,32,87,46,71,98,39) \) , using the insertion configuration method, the following steps:

Construct

Non-recursive algorithm

typedef struct BinarySortTreeNode{
    int data;
    struct BinarySortTreeNode *Left = NULL;
    struct BinarySortTreeNode *Right = NULL;
}*BinarySortTree;

BinarySortTree CreatBStree(int *a,int length) {
    BinarySortTree BST = new BinarySortTreeNode;
    BST->data = *a++;    
    for (int i = 1; i < length; i++) {
        BinarySortTreeNode *pre = NULL, *p = BST, *Node=new BinarySortTreeNode;
        while (p) {
            pre = p;
            p = *a < p->data ? p->Left : p->Right;
        }
        Node->data = *a;
        *a < pre->data ? pre->Left = Node : pre->Right = Node;
        a++;
    }
    return BST;
}

Recursive wording

BinarySortTree InsertBStree(BinarySortTree BST, int x){
    if (BST == NULL){
        BST = new BinarySortTreeNode;
        BST->data = x;
        return BST;
    }    
        if (x < BST->data)
            BST->Left = InsertBStree(BST->Left, x);
        else
            BST->Right = InsertBStree(BST->Right, x);
        return BST;
}
BinarySortTree CreatBStByRecursion(int *a,int length) {
    BinarySortTree BST = NULL;
    for (int i = 0; i < length; i++)
        BST = InsertBStree(BST, a[i]);
    return BST;
}

Insert and delete

Insert Node

This approach based on cycles can be used as "build binary sort tree" recursive algorithm written.

BinarySortTree InsertBStree(BinarySortTree BST, int x){
    if (BST == NULL){
        BST = new BinarySortTreeNode;
        BST->data = x;
        return BST;
    }    
        if (x < BST->data)
            BST->Left = InsertBStree(BST->Left, x);
        else
            BST->Right = InsertBStree(BST->Right, x);
        return BST;
}
BinarySortTree CreatBStByRecursion(int *a,int length) {
    BinarySortTree BST = NULL;
    for (int i = 0; i < length; i++)
        BST = InsertBStree(BST, a[i]);
    return BST;
}

Find node

  Can not find return NULL, returns to find the node.

BinarySortTreeNode* BSTreeFind(BinarySortTree BST,int x) {
    BinarySortTree p = BST;
    while (p) {
        if (x == p->data) break;
        p = x > p->data ? p->Right : p->Left;
    }
    return p;
}

Delete Node

  1. deleted is a leaf node, the parent node of the left or right pointer field is set to NULL.

  2. The node is deleted only the left sub-tree or only a right subtree, the nodes with the left or right to re-connect. And delete a single list node similar.

  (The first case, when you can write and second merged)

  3. deleted both the left subtree of the node, but also the right subtree, the nodes need to select the node to be deleted up to the position of its left subtree or have subtree according to the nature of binary sort tree. (Choose left and right can be selected)

If left selected sub-tree, you should choose the left sub-tree leaf node in the right-most (certainly leaves here, if not a leaf, then it is not the rightmost node)

If you select the right sub-tree, you should choose the right subtree leftmost leaf node.

Written 1:

This wording is more suitable for JAVA and the like, there is garbage collected language, the code can delete those omitted, but it must be noted that: You must call this Tree = BSTDel (Tree, delNum); like the inside of a recursive function Like the form, or delete a sub-tree root node only when an error occurs.

//获得子树中的最大值
int GetMax(BSTree root) {
    if (root->Right == NULL) return root->data;
    return GetMax(root->Right);
}
//删除子树中的最大值
BSTree DelMax(BSTree root) {
    if (root->Right == NULL) {
        BSTNode *t= root->Left;
        delete root;
        return t;
    }
    root->Right = DelMax(root->Right);
    return root;
}
BSTree BSTDel(BSTree root,int x) {
    if (root == NULL) return NULL;
    if (root->data == x) {
        if (! root->Right || !root->Left) {
            BSTNode *t = !root->Right ? root->Left : root->Right;
            delete root;
            return t;
        }
        root->data = GetMax(root->Left);
        root->Left = DelMax(root->Left);
    }
    else if (x > root->data) root->Right = BSTDel(root->Right, x);
    else  root->Left = BSTDel(root->Left, x);
    return root;
}

2 writing:

Pointer is very strong, pass into BSTree * root, you can change the value of * root directly. (Also annoying, above wording, if it is JAVA, no need to consider the problem delete, the amount of code can be shorter.)

Delete that part of the node contains two sub-trees, you can use imgthis idea to write, is not deleted, but with a maximum value of the node to find the value of the node is a direct replacement, then delete the maximum junction point, the effect is the same of,But I was fine bars, chosen to write complex

void BSTDel(BSTree *root, int x){
    if (!*root) {
        cout << "找不着" << endl;
        return;
    }
    BSTree p = *root;
    if (p->data == x) {
        if (!p->Right || !p->Left)
        *root = !p->Right ? p->Left : p->Right;
        else{
                BSTNode *parent = p->Left, *q = p->Left;
                if (!q->Right)    q->Right = p->Right;
                else {
                    while (q->Right) {
                        parent = q;
                        q = q->Right;
                    }
                    parent->Right = q->Left;
                    q->Left = p->Left;
                    q->Right = p->Right;
                }
                *root = q;
        }
        delete p;
    }
    else if (x > p->data) //向右找
        BSTDel(&(p->Right), x);
    else if (x < p->data) //向左找
        BSTDel(&(p->Left), x);
}

  The idea : binary sort tree thinking and quick sort of like a partition, root of the tree is first cut quick sort of sub-elements, the value of the left side than it is small, the value of the right side of it than the big, the same applies for all sub-trees, and fast recursive sort this sort of sub-array is corresponding.

miscellaneous:

//下面这是最开始写的,那个时候还不能理解BSTree *root是个什么含义。
//在删除只含单个子树的根节点时会出错。它是错的,但我还是要往上放,666。
void BSTreeDelete(BSTree root, int x) {
    if (!BSTreeFind(root, x)) return;
    BSTNode *pre = NULL, *p = root;
    while (x != p->data) {
        pre = p;
        p = x < p->data ? p->Left : p->Right;
    }
    //1. 左右子树都为空
    if (p->Left == NULL && p->Right == NULL) {
        p->data < pre->data ? pre->Left = NULL : pre->Right = NULL;
        delete p;
        return;
    }
    //2. 左子树或右子树为空
    if (p->Left == NULL) {
        p->data < pre->data ? pre->Left = p->Right : pre->Right = p->Right;
        delete p;
    }
    else if (p->Right == NULL) {
        p->data < pre->data ? pre->Left = p->Left : pre->Right = p->Left;
        delete p;
    }
    //3.左右子树都不为空
    else {
        BSTNode *pre = p->Left, *q = p->Left;
        while (q->Right) {
            pre = q;
            q = q->Right;
        }
        p->data = q->data;
        if (q == p->Left)
            p->Left = p->Left->Left;
        else //最右边的这个节点只可能有左子树
            pre->Right = q->Left;
        delete q;
    }
}

  General binary sort tree duplicated data is not allowed, if they are the same value in practical applications, it can be inserted into the left or right, as long as tree traversal when a non-strict in order to increase monotonically. But the need to look at the code, otherwise time will be looking for the wrong father. . .

BSTree BSTCreat(int *a,int length) {
    BSTree T = new BSTNode;
    T->data = *a++;    
    T->Left = NULL;
    T->Right = NULL;
    for (int i = 1; i < length; i++) {
        BSTNode *pre = NULL, *p = T, *Node=new BSTNode;
        while (p) {
            pre = p;
            p = *a < p->data ? p->Left : p->Right;
        }
        Node->data = *a;
        Node->Left = NULL; Node->Right = NULL;
        *a < pre->data ? pre->Left = Node : pre->Right = Node;
        a++;
    }
    return T;
}

Guess you like

Origin www.cnblogs.com/czc1999/p/11782562.html