71 Query Rank Min Max Successor of BST

【本文链接】

http://www.cnblogs.com/hellogiser/p/query-min-max-successor-of-bst.html

【代码】

 C++ Code 
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/9/18
*/


// binary tree node struct
struct BinaryTreeNode
{
    
int value;
    BinaryTreeNode *parent; 
// for rank of bst
    BinaryTreeNode *left;
    BinaryTreeNode *right;
    
int size; // for kmin of bst
    // x.size = x.left.size + x.right.size +1
};

int node_size(BinaryTreeNode *node)
{
    
// get node size of node
    if (node == NULL)
        
return 0;
    node->size = node_size(node->left) + node_size(node->right) + 
1;
    
return node->size;
}

int left_size(BinaryTreeNode *node)
{
    
// get left size of node in o(1)
    return node->left != NULL ? node->left->size : 0;
}

//=================================================
// BST Tree  kmin
//=================================================
BinaryTreeNode *kmin_bst(BinaryTreeNode *root, int k)
{
    
if (root == NULL)
        
return NULL;

    
int pk = left_size(root) + 1// get node rank first

    
if (k == pk)
    {
        
return root;
    }
    
else if (k < pk)
    {
        
return kmin_bst(root->left, k);
    }
    
else // k>pk
    {
        
return kmin_bst(root->right, k - pk);
    }
}

BinaryTreeNode *Kmin_of_BST(BinaryTreeNode *root, 
int k)
{
    
if (root == NULL)
        
return NULL;
    
// get node size of bst first
    int nodes = node_size(root);
    
if (k < 1 || k > nodes)
        
return NULL;
    
// use node size info to get kmin of bst
    return kmin_bst(root, k);
}


//=================================================
// BST Tree  querying
//=================================================
BinaryTreeNode *Search_of_BST(BinaryTreeNode *root, int key)
{
    
if (root == NULL)
        
return NULL;
    
if (key == root->value)
        
return root;
    
else if(key < root->value)
        
return Search_of_BST(root->left, key);
    
else
        
return Search_of_BST(root->right, key);
}

BinaryTreeNode *Search_of_BST2(BinaryTreeNode *root, 
int key)
{
    BinaryTreeNode *node = root;
    
while (node != NULL && key != node->value)
    {
        
if (key < node->value)
            node = node->left;
        
else
            node = node->right;
    }
    
return node;
}

BinaryTreeNode *Min_of_BST(BinaryTreeNode *root)
{
    
if (root == NULL)
        
return NULL;
    BinaryTreeNode *node = root;
    
while(node->left != NULL)
        node = node->left;
    
return node;
}

BinaryTreeNode *Max_of_BST(BinaryTreeNode *root)
{
    
if(root == NULL)
        
return NULL;
    BinaryTreeNode *node = root;
    
while(node->right != NULL)
        node = node->right;
    
return node;
}

/*
x has right child ===> Min(x.right)           (case 1)
else px = x.parent                            (case 2)

if px.right == x ===> go up until px==null   (case 2.2)
else px.left ==x ===> px                     (case 2.1)
*/

BinaryTreeNode *Successor(BinaryTreeNode *x)
{
    
if(x == NULL)
        
return NULL;
    
// case 1
    if (x->right != NULL)
        
return Min_of_BST(x->right);
    
// case 2
    BinaryTreeNode *px = x->parent;
    
if(px == NULL)
        
return NULL;
    
// case 2.1
    if (px->left == x)
        
return px;
    
// case 2.2
    while(px != NULL && px->right == x)
    {
        x = px;
        px = px->parent;
    }
    
return px;
}


/*
        px                 px
       /                     \
      x                       x
*/

/*
get all node size first

rank = leftsize(x)+1
px = x.parent
if px.right ==x ====> rank += leftsize(px)+1, go up
else rank += 0
*/

int Rank_of_BST(BinaryTreeNode *root, BinaryTreeNode *x)
{
    
if(root == NULL || x == NULL)
        
return -1;
    
// get node size first
    node_size(root);

    
int rank = left_size(x) + 1;
    
// parent's left or right child ?
    BinaryTreeNode *px = x->parent;
    
while(px != NULL)
    {
        
if (px->right == x)
        {
            
// px's right child
            rank += left_size(px) + 1;
        }
        px = px->parent;
    }
    
return rank;
}