Loading

二叉搜索树

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

数据类型设计:

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 }
posted @ 2014-07-18 12:16  dai.sp  阅读(240)  评论(0编辑  收藏  举报