二叉查找树

1.二叉查找树又称为二叉搜索树。二叉查找树和普通的二叉树在结构上一样,它要么是一棵空树,要么是这样的一棵二叉树:对任意结点,如果左子树不为空,则左子树上所有结点的权值都小于该结点的权值;如果右子树不为空,则右子树上所有结点的权值都大于该结点的权值;任意结点的左子树和右子树都是一棵二叉查找树;一般而言, 二叉查找树上结点的权值都是唯一的。

  • 在二叉排序树上,对于任意结点,如果有左子树和右子树,那么其左子树上结点的权值都小于右子树上结点的权值。
  • 如果中序遍历二叉排序树,会得到一个从小到大的序列。
  • 二叉排序树的插入和查找效率相对较高,最坏情况下时间复杂度为 O(n),期望的时间复杂度为 O(logn),其中 n 为树上结点总个数。

刚才我们提到了二叉排序树最坏情况下时间复杂度为 O(n),这是为什么呢?最坏情况下,二叉排序树会退化成链表,从根结点往左依次递减,或者从根结点往右依次递增。那有什么方法可以解决这个问题呢?在二叉排序树的基础上可以加些优化,可以让其成为 AVL 树,红黑树,SBT,Splay 等等,这些高级的树结构解决了上面的问题,插入和查找的效率均为 O(logn)。

2.二叉排序树的性质

  • 一般而言,二叉排序树上结点的权值是唯一的
  • 在二叉排序树上,对于任意结点,如果有左子树和右子树,那么左子树上结点的权值小于右子树上结点的权值。
  • 如果中序遍历二叉排序树,可以得到一个从小到大的序列
  • 二叉排序树插入查找的效率都是 O(logn),最坏情况下是 O(n)

3.二叉查找树的构造,插入,查找,删除

  1 #include<iostream>
  2 using namespace std;
  3 class Node {
  4 public:
  5     int data;
  6     Node *lchild, *rchild, *father;
  7     Node(int _data, Node *_father = NULL) {
  8         data = _data;
  9         lchild = NULL;
 10         rchild = NULL;
 11         father = _father;
 12     }
 13     ~Node() {
 14         if (lchild != NULL) {
 15             delete lchild;
 16         }
 17         if (rchild != NULL) {
 18             delete rchild;
 19         }
 20     }
 21     void insert(int value) {               //二叉查找树的插入(递归)
 22         if (value == data) {
 23             return;
 24         } else if (value > data) {
 25             if (rchild == NULL) {
 26                 rchild = new Node(value, this);
 27             } else {
 28                 rchild->insert(value);
 29             }
 30         } else {
 31             if (lchild == NULL) {
 32                 lchild = new Node(value, this);
 33             } else {
 34                 lchild->insert(value);
 35             }
 36         }
 37     }
 38     Node* search(int value) {           //二叉查找树的查找(递归)
 39         if (data == value) {
 40             return this;
 41         } else if (value > data) {
 42             if (rchild == NULL) {
 43                 return NULL;
 44             } else {
 45                 return rchild->search(value);
 46             }
 47         } else {
 48             if (lchild == NULL) {
 49                 return NULL;
 50             } else {
 51                 return lchild->search(value);
 52             }
 53         }
 54     }
 55     Node* predecessor() {              //找节点的前驱(左孩子节点孩子不为空)
 56         Node *temp = lchild;
 57         while (temp != NULL && temp->rchild != NULL) {
 58             temp = temp->rchild;
 59         }
 60         return temp;
 61     }
 62     Node* successor() {                //找节点的后继(右孩子节点不为空)
 63         Node *temp = rchild;
 64         while (temp != NULL && temp->lchild != NULL) {
 65             temp = temp->lchild;
 66         }
 67         return temp;
 68     }
 69     void remove_node(Node *delete_node) {   //删除度为1或0的节点
 70         Node *temp = NULL;
 71         if (delete_node->lchild != NULL) {
 72             temp = delete_node->lchild;
 73             temp->father = delete_node->father;
 74             delete_node->lchild = NULL;
 75         }
 76         if (delete_node->rchild != NULL) {
 77             temp = delete_node->rchild;
 78             temp->father = delete_node->father;
 79             delete_node->rchild = NULL;
 80         }
 81         if (delete_node->father->lchild == delete_node) {
 82             delete_node->father->lchild = temp;
 83         } else {
 84             delete_node->father->rchild = temp;
 85         }
 86         delete delete_node;
 87     }
 88     bool delete_tree(int value){     //二叉查找树的删除
 89         Node *delete_node,*current_node;
 90         current_node=search(value);
 91         if(current_node==NULL){
 92             return false;
 93         }
 94         if(current_node->lchild!=NULL){
 95             delete_node=current_node->predecessor();
 96         }
 97         else if(current_node->rchild!=NULL){
 98             delete_node=current_node->successor();
 99         }
100         else{
101             delete_node=current_node;
102         }
103         current_node->data=delete_node->data;//先替换,再转化为度为0的情况
104         remove_node(delete_node);
105         return true;
106     }
107 };
108 class BinaryTree {
109 private:
110     Node *root;
111 public:
112     BinaryTree() {
113         root = NULL;
114     }
115     ~BinaryTree() {
116         if (root != NULL) {
117             delete root;
118         }
119     }
120     void insert(int value) {
121         if (root == NULL) {
122             root = new Node(value);
123         } else {
124             root->insert(value);
125         }
126     }
127     bool find(int value) {
128         if (root->search(value) == NULL) {
129             return false;
130         } else {
131            return true;
132         }
133     }
134     bool delete_tree(int value){
135         return root->delete_tree(value);
136     }
137 };
138 int main() {
139     BinaryTree binarytree;
140     int arr[10] = { 8, 9, 10, 3, 2, 1, 6, 4, 7, 5 };
141     for (int i = 0; i < 10; i++) {
142         binarytree.insert(arr[i]);
143     }
144     int value;
145     cin >> value;
146     if (binarytree.find(value)) {
147         cout << "search success!" << endl;
148     } else {
149         cout << "search failed!" << endl;
150     }
151     cin>>value;
152     if(binarytree.delete_tree(value)){
153         cout<<"delete success!"<<endl;
154     }
155     else{
156         cout<<"delete failed!"<<endl;
157     }
158     return 0;
159 }

 

转载于:https://www.cnblogs.com/Reindeer/p/5691363.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值