• 二叉搜索树


    以下是二叉搜索树中查找、插入、删除的递归和非递归算法

    数据类型设计:

    1 struct BSTNode 
    2 {
    3     ElementType data;               // 结点元素值
    4     struct Node *leftChild;         // 左子树根结点
    5     struct Node *rightChild;        // 右子树根结点
    6 };

    查找数据:

     1 // 递归算法
     2 bool findBSTree(BSTNode *root, ElementType item)
     3 {
     4     if(root == NULL)                                           // 若二叉搜索树为空,返回假,结束查找
     5         return false;           
     6     else {                                                     // 若二叉搜索树不为空,则item与根结点的元素值比较
     7         if(item == root->data)                                 // 若等于根结点的元素值
     8             return true;           
     9         else if(item < root->data)           
    10             return findBSTree(root->leftChild, item);          // 若小于根结点的元素值,则递归搜索根结点的左子树
    11         else           
    12             return findBSTree(root->rightChild, item);         // 若大于根结点的元素值,则递归搜索根结点的右子树
    13     }           
    14 }           
    15            
    16 // 非递归算法           
    17 bool findBSTree(BSTNode *root, ElementType item)           
    18 {           
    19     if(root == NULL)                                           // 若二叉搜索树为空,则查找失败
    20         return false;           
    21     BSTNode *current = root;           
    22     while(current != NULL) {                                   /* 重复搜索,直到叶子结点 */
    23         if(item == current->data)                              // 若查找到
    24             return true;           
    25         else if(item < current->data)                          // 若目标元素小于当前结点,则在左子树中查找
    26             current = current->leftChild;           
    27         else                                                   // 若目标元素大于当前结点,则在右子树中查找
    28             current = current->rightChild;
    29     }
    30     return false;
    31 }

    插入数据:

     1 // 递归算法
     2 void insertBSTreeNode(BSTNode *BST, ElementType item)
     3 {
     4     if(BST == NULL) {                                                /* 若二叉搜索树为空,则新结点作为根结点插入 */
     5         BSTNode *temp = new BSTNode;
     6         temp->data = item;
     7         temp->leftChild = temp->rightChild = NULL;
     8         BST = temp;
     9     } else if(item < BST->data)                                      /* 新结点插入到左子树中 */
    10         insertBSTreeNode(BST->leftChild, item);
    11     else                                                             /* 新结点插入到右子树中 */
    12         insertBSTreeNode(BST->rightChild, item);
    13 }
    14 
    15 // 非递归算法
    16 void insertBSTreeNode(BSTNode *BST, ElementType item)
    17 {
    18     BSTNode *newNode = new BSTNode;
    19     newNode->data = item;
    20     newNode->leftChild = NULL;
    21     newNode->rightChild = NULL;
    22 
    23     BSTNode *current = BST;
    24     /* 若二叉搜索树为空,则新结点为根结点 */
    25     if(current == NULL) {            
    26         BST = newNode;
    27         return ;
    28     }
    29     /* 重复查找插入位置,直到新结点插入 */
    30     while(current->leftChild != newNode && current->rightChild != newNode) {
    31         if(item < current->data) {                                            // 新元素小于当前比较结点值,向左子树查找
    32             if(current->leftChild != NULL)                                    // 若左孩子存在,使左孩子成为当前结点
    33                 current = current->leftChild;
    34             else
    35                 current->leftChild = newNode;                                 // 左孩子不存在,则新结点为当前结点的左孩子
    36         } else {                                                              // 新元素不小于当前比较结点,则向右子树查找
    37             if(current->rightChild != NULL)                                   // 若右孩子存在,则使右孩子成为当前结点
    38                 current = current->rightChild;
    39             else
    40                 current->rightChild = newNode;                                // 若右孩子不存在,则新结点为当前结点的右孩子
    41         }
    42     }
    43 }
    44 
    45 // 非递归算法
    46 void Insert(Link &head, Item item)
    47 {
    48     BSTNode *pre = NULL, *curr = NULL;                   // 空树
    49     if (head == NULL) {
    50         head = new BSTNode(item);                        // 构造新结点
    51         return ;
    52     }
    53     pre = head;                                          // 从根节点开始查找
    54     curr = pre;
    55     while (curr != NULL) {
    56         if (item.val == curr->item.val)
    57             return ;                                     // 查找成功,返回
    58         if (item.val < curcurr->item.val)                // item的值小于当前结点值
    59             curr = curr->left;                           // 搜索左子树
    60         else
    61             curr = curr->right;                          // item的值大于当前结点值,搜索右子树
    62         pre = curr ? curr : pre;
    63     }
    64     if(item.val == pre->item.val)                        // 查找成功,返回
    65         return ;
    66     if(item.val < pre->item.val)                         // 小于当前结点
    67         pre->left = new BSTNode(item);                   // 构造新结点作为当前结点的左孩子
    68     else
    69         pre->right = new BSTNode(item);                  // 大于当前结点,构造新结点作为当前结点的右孩子
    70 }

     删除数据:

      1  // 递归算法    注意:传进来的根结点指针是引用类型的!!!
      2 bool deleteBSTreeNode(BSTNode * &BST, ElementType item)
      3 {
      4     /* 若二叉树为空,则删除失败 */
      5     if(BST == NULL)
      6         return false;
      7     /* 若根结点就是要删除的结点 */
      8     if(item == BST->data) {                                            
      9         BSTNode * temp = BST;                                                 // 记下根结点指针
     10         if(BST->leftChild == NULL) {                                          // 若左子树为空树,则右孩子即为删除后的根结点
     11             BST = BST->rightChild;
     12             delete temp;
     13             return true;
     14         } else if(BST->rightChild == NULL) {                                  // 若右子树为空,左孩子即为删除后的根结点
     15             BST = BST->leftChild;
     16             delete temp;
     17             return true;
     18         } else {                                                              // 若左右子树均不为空
     19             if(BST->leftChild->rightChild == NULL) {                        // 若左孩子无右子树,左孩子就是根结点的中序前件
     20                 BST->data = BST->leftChild->data;                             // 中序前件的值赋给根结点
     21                 return deleteBSTreeNode(BST->leftChild, BST->leftChild->data);// 删除左子树的根结点,并返回删除结果
     22             } else {                                                          // 若左孩子有右子树
     23                 BSTNode *prev = BST;
     24                 BSTNode *current = BST->leftChild;
     25                 while(current->rightChild != NULL) {                       // 找根结点的中序前件(左子树的最右边的一个结点)
     26                     prev = current;
     27                     current = current->rightChild;
     28                 }
     29                 BST->data = current->data;                                    // 中序前件的值赋给根结点
     30                 return deleteBSTreeNode(current, current->data);              // 删除中序前件结点,并返回删除结果
     31             }
     32         }
     33     }
     34     /* 若待删除元素小于根结点值 */
     35     if(item < BST->data)
     36         return deleteBSTreeNode(BST->leftChild, item);                        // 递归到左子树中查找并作删除,返回删除结果
     37     /* 若待删除元素大于根结点值 */
     38     if(item > BST->data)
     39         return deleteBSTreeNode(BST->rightChild, item);                       // 递归到右子树中查找并作删除,返回删除结果
     40 }
     41 
     42 // 非递归算法
     43 bool deleteBSTreeNode(BSTNode *BST, ElementType item)
     44 {
     45     BSTNode *current = BST, *prior = NULL;                          // current为当前比较的结点,prior为current的父亲结点
     46     /* 从二叉搜索树根结点开始查找要删除的结点 */
     47     while(current != NULL && current->data != item) {
     48         prior = current;
     49         if(item < current->data)                                    // item小于current结点值,则向左子树中查找
     50             current = current->leftChild;
     51         else 
     52             current = current->rightChild;                          // item不小于current结点值,则向右子树查找
     53     }
     54     /* 没找到目标元素 */
     55     if(current == NULL)
     56         return false;
     57     /* 找到目标结点,执行删除目标结点操作 */
     58     if(current->leftChild == NULL && current->rightChild == NULL) { /***** current为叶子结点 */
     59         if(current == BST)                                          // current为根结点
     60             BST = NULL;
     61         else {                                                      // current不为根结点
     62             if(prior->leftChild == current)                         // current是父结点prior的左孩子
     63                 prior->leftChild = NULL;
     64             else                                                    // current是父结点prior的右孩子
     65                 prior->rightChild = NULL;
     66         }
     67     } else if(current->leftChild == NULL) {                         /***** current是只有右孩子的单支结点 */
     68         if(current == BST)                                          // current为根结点
     69             BST = current->rightChild;
     70         else {
     71             if(current == prior->leftChild)                         // current是父结点prior的左孩子
     72                 prior->leftChild = current->rightChild;
     73             else                                                    // current是父结点prior的右孩子
     74                 prior->rightChild = current->rightChild;
     75         }
     76     } else if(current->rightChild == NULL) {                        /***** current是只有左孩子的单支结点 */
     77         if(current == BST)                                          // current为根结点
     78             BST = current->leftChild;
     79         else {
     80             if(current == prior->leftChild)                         // current是父点prior的左孩子
     81                 prior->leftChild = current->leftChild;
     82             else                                                    // current是父节点prior的右孩子
     83                 prior->rightChild = current->leftChild;
     84         }
     85     } else {                                                        /***** current为双支结点 */
     86         /* 查找current的中序前件结点 */
     87         BSTNode *inorderPrevious = current->leftChild;              // current结点的中序前件inorderPrevious
     88         BSTNode *previous = current;                                // previous记下inorderPrevious的父结点
     89         while(inorderPrevious->rightChild != NULL) {
     90             previous = inorderPrevious;
     91             inorderPrevious = inorderPrevious->rightChild;
     92         }
     93         previous->rightChild = inorderPrevious->leftChild;          // 将inorderPrevious的左子树上移到它本身所在的位置
     94         inorderPrevious->leftChild = current->leftChild;            // 使current的左右子树成为inorderPrevious的左右子树
     95         inorderPrevious->rightChild = current->rightChild;
     96         if(current == BST)                       // 若current结点是根结点,则inorderPrevious成为根结点
     97             BST = inorderPrevious;
     98         else {                                   // 若current结点不是根结点,用inorderPrevious替代current在二叉树中的位置
     99             if(current == prior->leftChild)
    100                 prior->leftChild = inorderPrevious;
    101             else
    102                 prior->rightChild = inorderPrevious;
    103         }
    104     }
    105 }
  • 相关阅读:
    JS闭包中的循环绑定处理程序
    Java学习之路-Spring的HttpInvoker学习
    Java学习之路-Burlap学习
    Java学习之路-Hessian学习
    Java学习之路-RMI学习
    现代浏览器的工作原理
    Socket Connect问题
    Tair总述
    TCP协议解析
    数据结构 之 二叉堆(Heap)
  • 原文地址:https://www.cnblogs.com/gotodsp/p/3853225.html
Copyright © 2020-2023  润新知