二叉查找树(BST)

二叉查找树递归定义:

二叉查找树是空树或不是空树
二叉查找树的左二叉查找树的值一定小于二叉查找树的值或左二叉查找树为空树
二叉查找树的右二叉查找树的值一定大于二叉查找树的值或右二叉查找树为空树

不维护父亲域的,坑爹啊。

放上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
#include <string>
using namespace std;
 
#define NEW(d) new BST(d)
 
struct BST {
    BST *lc, *rc;
    int data;
    BST() : lc(0), rc(0) {}
    BST(int d) : lc(0), rc(0), data(d) {}
}*root = NULL;
 
typedef BST* tree;
 
void insert(int d) {
    if(root == NULL) { root = NEW(d); return;}
    tree t, now = root;
    //二分找到合适的位置,t是指向这个合适的位置的指针
    while(now != NULL) {
        t = now;
        if(now-> data > d) now = now-> lc;
        else now = now-> rc;
    }
    //插入新值到左边(或右边)
    if(t-> data > d) t-> lc = NEW(d);
    else t-> rc = NEW(d);
}
//没有父亲域的这个就是巨坑
void del(int d) {
    tree t, q = root, rt = root;
    while(rt != NULL && rt-> data != d) {
        q = rt;
        if(rt-> data > d) rt = rt-> lc;
        else rt = rt-> rc;
    }
    //如果删除的是root
    if(q == root) {delete root; root = NULL; return;}
    //如果不存在
    if(rt == NULL) return;
    //如果有一边是空的,那么将另一棵子树拉上来即可,在这里,已经包含了当两边都是空树时
    if(rt-> lc == NULL) {
        if(q-> lc == rt) q-> lc = rt-> rc;
        else q-> rc = rt-> rc;
        delete rt;
        return;
    }
    if(rt-> rc == NULL) {
        if(q-> lc == rt) q-> lc = rt-> lc;
        else q-> rc = rt-> lc;
        delete rt;
        return;
    }
    t = rt;
    q = rt-> rc;
    while(q-> lc) {
        t = q;
        q = q-> lc;
    }
    rt-> data = q-> data;
    if(t != rt) t-> lc = q-> rc;
    else t-> rc = q-> rc;
    delete q;
}
 
tree search(int d) {
    tree ret = root;
    while(ret != NULL && ret-> data != d) {
        if(ret-> data > d) ret = ret-> lc;
        else ret = ret-> rc;
    }
    return ret;
}
 
tree max(){
    if(root == NULL) return NULL;
    tree ret = root;
    while(ret-> rc) ret = ret-> rc;
    return ret;
}
 
tree min(){
    if(root == NULL) return NULL;
    tree ret = root;
    while(ret-> lc) ret = ret-> lc;
    return ret;
}
 
void out(string str) {
    cout << str;
}
 
 
int main() {
    out("1: insert\n2: del\n3: search\n4: max\n5: min\n");
    int c, t;
    tree a;
    while(cin >> c) {
        switch(c) {
        case 1: cin >> t;
                insert(t);
                break;
        case 2: cin >> t;
                del(t);
                break;
        case 3: cin >> t;
                if(search(t) == NULL) out("Not here\n");
                else out("Is here!\n");
                break;
        case 4: a = max();
                if(a != NULL) cout << a-> data << endl;
                else out("Warn!\n");
                break;
        case 5: a = min();
                if(a != NULL) cout << a-> data << endl;
                else out("Warn!\n");
                break;
        default:
                break;
        }
    }
    return 0;
}

 因为有些坑爹,所以还是写递归版的del

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void del(tree& rt, int d) {
    if(rt == NULL) return;
    if(rt-> data > d) del(rt-> lc, d);
    else if(rt-> data < d) del(rt-> rc, d);
    else {
        tree q, t;
        if(rt-> lc == NULL) {
            q = rt;
            rt = rt-> rc;
            delete q;
            return;
        }
        if(rt-> rc == NULL) {
            q = rt;
            rt = rt-> lc;
            delete q;
            return;
        }
        q = rt-> rc, t = rt;
        //找后继
        while(q-> lc != NULL) {
            t = q;
            q = q-> lc;
        }
        rt-> data = q-> data;
        //当后继就是右子女,那么要将后继的右子女接到节点右边
        if(rt == t) t-> rc = q-> rc;
        //否则就要给后继的父亲的左子女赋值为后继的右子女
        else t-> lc = q-> rc;
        delete q;
    }
}

 

写个简洁的把,,,维护个父亲域。。旋转也好写了= =。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include <string>
using namespace std;
 
#define NEW(d) new BST(d)
 
struct BST {
    BST *lc, *rc, *pa;
    int data;
    BST() : lc(0), rc(0), pa(0) {}
    BST(int d) : lc(0), rc(0), pa(0), data(d) {}
    //BST operator= (BST& a) { lc = a.lc; rc = a.rc; pa = a.pa; data = a.data; return *this; }
}*root = NULL;
 
typedef BST* tree;
 
void insert(int d) {
    if(root == NULL) { root = NEW(d); return;}
    tree t, now = root;
    //二分找到合适的位置,t是指向这个合适的位置的指针
    while(now != NULL) {
        t = now;
        if(now-> data > d) now = now-> lc;
        else now = now-> rc;
    }
    //插入新值到左边(或右边)
    if(t-> data > d) t-> lc = NEW(d), t-> lc-> pa = t;
    else t-> rc = NEW(d), t-> rc-> pa = t;
}
 
tree search(int d) {
    tree ret = root;
    while(ret != NULL && ret-> data != d) {
        if(ret-> data > d) ret = ret-> lc;
        else ret = ret-> rc;
    }
    return ret;
}
 
void del(int d) {
    tree rt = search(d), t, q;
    if(rt == root) { delete root; root = NULL; return; }
    if(rt == NULL) return;
    if(rt-> lc == NULL) {
        if(rt-> pa-> lc == rt) rt-> pa-> lc = rt-> rc;
        else rt-> pa-> rc = rt-> rc;
        delete rt;
        return;
    }
    if(rt-> rc == NULL) {
        if(rt-> pa-> lc == rt) rt-> pa-> lc = rt-> lc;
        else rt-> pa-> rc = rt-> lc;
        delete rt;
        return;
    }
    q = rt-> rc, t = rt;
    while(q-> lc) {
        t = q;
        q = q-> lc;
    }
    rt-> data = q-> data;
    if(t != rt) t-> rc = q-> rc;
    else t-> lc = q-> rc;
    delete q;
}
 
tree max(){
    if(root == NULL) return NULL;
    tree ret = root;
    while(ret-> rc) ret = ret-> rc;
    return ret;
}
 
tree min(){
    if(root == NULL) return NULL;
    tree ret = root;
    while(ret-> lc) ret = ret-> lc;
    return ret;
}
 
void out(string str) {
    cout << str;
}
 
 
int main() {
    out("1: insert\n2: del\n3: search\n4: max\n5: min\n");
    int c, t;
    tree a;
    while(cin >> c) {
        switch(c) {
        case 1: cin >> t;
                insert(t);
                break;
        case 2: cin >> t;
                del(t);
                break;
        case 3: cin >> t;
                if(search(t) == NULL) out("Not here\n");
                else out("Is here!\n");
                break;
        case 4: a = max();
                if(a != NULL) cout << a-> data << endl;
                else out("Warn!\n");
                break;
        case 5: a = min();
                if(a != NULL) cout << a-> data << endl;
                else out("Warn!\n");
                break;
        default:
                break;
        }
    }
    return 0;
}

  

 

二叉查找树(BST)

上一篇:Linux 查找文件命令 find whereis locate


下一篇:RuleML 入门(上)