binary search tree

  The definition of a binary tree is that each node of a tree has at most two children, and the property that makes a binary tree a binary search tree is that for each node X in the tree, the keys in its left subtree are greater than those in X is small, and its right subtree is larger than the key in X.

  A binary tree node can be defined as follows:

1  struct BSTreeNode {
 2      BSTreeNode * pLeft;
3      BSTreeNode * pRight;
4      int nData;
5 };

  The binary tree is very simple. Here are a few basic operations.

  1. Insert

    Inserting a keyword Key starts from the root node. If the Key is larger than the keyword of this node, continue to the right until the node is empty. The following code is non-recursive writing, and it is very easy to write recursive writing.

 1 //返回树的根节点
 2 BSTreeNode* BSTreeInsert(BSTreeNode* pRoot, int nData) {
 3     if (pRoot == nullptr) {
 4         pRoot = new BSTreeNode;
 5         pRoot->pLeft = pRoot->pRight = nullptr;
 6         pRoot->nData = nData;
 7     }
 8     else {
 9         BSTreeNode* pParent = pRoot;
10         BSTreeNode* pCursor = pParent;
11         while (pCursor) {
12             pParent =pCursor;
13              if (nData> pCursor-> nData)
 14                  pCursor = pCursor-> pRight;
15              else  if (nData <pCursor-> nData)
 16                  pCursor = pCursor-> pLeft;
17              else 
18                  return pRoot;
19          }
 20          pCursor = new BSTreeNode;
21          pCursor-> nData = nData;
22          pCursor-> pLeft = pCursor-> pRight = nullptr;
23          if (nData> pParent-> nData)
 24             pParent-> pRight = pCursor;
25          else  if (nData <pParent-> nData)
 26              pParent-> pLeft = pCursor;
27      }
 28      return pRoot;
29 }}

  2. Get the minimum value

    Traverse all the way to the left until the node is empty.

 1 BSTreeNode* BSTreeMinimumNode(BSTreeNode* pRoot) {
 2     if (pRoot == nullptr)
 3         return nullptr;
 4 
 5     BSTreeNode* pCursor = pRoot;
 6     while (pCursor->pLeft) {
 7         pCursor = pCursor->pLeft;
 8     }
 9     return pCursor;
10 }

  3. Get the maximum value

    Traverse to the right until the node is empty.

 1 BSTreeNode* BSTreeMaximumNode(BSTreeNode* pRoot) {
 2     if (pRoot == nullptr)
 3         return nullptr;
 4 
 5     BSTreeNode* pCursor = pRoot;
 6     while (pCursor->pRight) {
 7         pCursor = pCursor->pRight;
 8     }
 9     return pCursor;
10 }

  4. Delete

    The deletion of a binary search tree is a little more complicated. First, find the node to be deleted in the tree. When the node is found (set as X), first determine whether the left child node and the right child node are empty. If any child node is empty , the deletion is very easy, just replace the node to be deleted with the sibling node of the empty node. And if the left child node and the right child node are not empty, find a node with the smallest value (set as Y) in the right subtree of the node to be deleted, and then assign the value of this smallest node to the node to be deleted X , and then delete the smallest node Y in the right subtree, and Y must be empty of the left child node, the deletion will be very simple. code show as below:

1 BSTreeNode * BSTreeDelete (BSTreeNode * pRoot, int nData) {
 2      if (pRoot == nullptr)
 3          return nullptr;
4      else  if (nData> pRoot-> nData) {
 5          pRoot-> pRight = BSTreeDelete (pRoot-> pRight, nData);
6          return pRoot;
7      }
 8      else  if (nData <pRoot-> nData) {
 9          pRoot-> pLeft = BSTreeDelete (pRoot-> pLeft, nData);
10          return pRoot;
11      }
 12      else {
13         if (pRoot->pLeft == nullptr || pRoot->pRight == nullptr) {
14             BSTreeNode* pNode = (pRoot->pRight == nullptr) ? pRoot->pLeft : pRoot->pRight;
15             delete pRoot;
16             return pNode;
17         }
18         else {
19             BSTreeNode* pNode = BSTreeMinimumNode(pRoot->pRight);
20             pRoot->nData = pNode->nData;
21             pRoot->pRight = BSTreeDelete(pRoot->pRight, pNode->nData);
22             return pRoot;
23         }
24     }
25 }

  The return value is the root node of the passed tree after nData has been removed. After deletion, through recursive backtracking, assign the return value to the left subtree or right subtree corresponding to the original node.

  In "Introduction to Algorithms", non-recursive deletion is used, so if the left and right child nodes of X are not empty, when searching for the successor node Y (that is, the smallest node) in the right subtree, it also discusses if the successor If Y is the right child node of X, if it is the right child node, replace X with Y directly, otherwise replace the value in X with the right child node of Y, and then replace Y with the right child node of Y. Personally, I feel that the code for recursive deletion is not as concise and clear. And in the non-recursive deletion, the node must keep a reference to the parent node, that is to say, a parent node pointer must be added to the definition of the node.

  Five, binary tree traversal

    There are three traversal methods for binary tree traversal: pre-order traversal, in-order traversal, and post-order traversal

    Preorder traversal: itself, left child, right child.

    Inorder traversal: left child, itself, right child.

    Postorder traversal: left child, right child, itself.

  Take the following binary tree as an example:

      

  Preorder traversal output: ABDECFG

  Inorder traversal output: DBEAFCG

  Post-order traversal output: DEBFGCA

  It can be seen from the above that the output of in-order traversal is sorted results.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325250664&siteId=291194637