一个简易的元素不重复的二叉搜索树链表的实现
不知道为什么, 之前好几篇博客都被一些不出名的小网站抄了。 其实我写这些博客的目的是练手, 但是当知道被人抄了而自己却毫不知情, 还是有些蛋疼的。
代码如下:
1 struct TreeNode;
2 typedef shared_ptr<TreeNode> PTreeNode;
3
4 struct TreeNode
5 {
6 int32_t key = 0;
7 PTreeNode leftChild = nullptr;
8 PTreeNode rightChild = nullptr;
9
10 // 此处若设为 shared_ptr, 则会导致循环引用.
11 weak_ptr<TreeNode> parent;
12
13 PTreeNode& MoveToNextNode (const int32_t& value)
14 {
15 return key < value ? rightChild : leftChild;
16 }
17 };
18
19 class BinarySearchTree
20 {
21 private:
22 PTreeNode root;
23
24 PTreeNode MakeNewNode (const int32_t& value)
25 {
26 auto newNode = make_shared<TreeNode> ();
27 newNode->key = value;
28 return newNode;
29 }
30 enum Direction { left, right };
31 PTreeNode GetEdgeNode (PTreeNode node, const Direction&);
32 // Return the node which the key is lowest but greater than parm node.
33 PTreeNode Successor (PTreeNode);
34 bool IsLeftChild (const PTreeNode& node)
35 {
36 return node->parent.lock ()->leftChild == node;
37 }
38 void TransferParent (const PTreeNode&, const PTreeNode&);
39 public:
40 PTreeNode MaxNode (PTreeNode node = nullptr)
41 {
42 if (node == nullptr) {
43 node = root;
44 }
45 return GetEdgeNode (node, right);
46 }
47 PTreeNode MinNode (PTreeNode node = nullptr)
48 {
49 if (node == nullptr) {
50 node = root;
51 }
52 return GetEdgeNode (node, left);
53 }
54 PTreeNode Search (const int32_t&);
55 void Insert (const int32_t&);
56 void Delete (const int32_t&);
57 };
58
59 void BinarySearchTree::TransferParent (const PTreeNode& parent, const PTreeNode& child)
60 {
61 if (child != nullptr) {
62 child->parent = parent->parent;
63 }
64
65 // The target node is root.
66 if (parent->parent.expired ()) {
67 root = child;
68 }
69 else {
70 if (IsLeftChild (parent)) {
71 parent->parent.lock ()->leftChild = child;
72 }
73 else {
74 parent->parent.lock ()->rightChild = child;
75 }
76 }
77 }
78 PTreeNode BinarySearchTree::GetEdgeNode (PTreeNode node, const Direction& dir)
79 {
80 auto result = node;
81 auto NextNode = [&] ()
82 {
83 if (dir == left) {
84 return result->leftChild;
85 }
86 else {
87 return result->rightChild;
88 }
89 };
90
91 while (NextNode () != nullptr) {
92 result = NextNode ();
93 }
94 return result;
95 }
96 PTreeNode BinarySearchTree::Successor (PTreeNode node)
97 {
98 // If the node has right subtree, return the min of the right subtree.
99 if (node->rightChild != nullptr) {
100 return MinNode (node->rightChild);
101 }
102
103 // Otherwise the node has the greatest key in it's subtree.
104 auto currentParent = node->parent.lock ();
105
106 // Search upward, until get a node
107 // which the left child is the head of the subtree that the node stay in.
108 while (currentParent != nullptr && node == currentParent->rightChild) {
109 node = currentParent;
110 currentParent = currentParent->parent.lock ();
111 }
112
113 // And return that node.
114 return currentParent;
115 }
116 PTreeNode BinarySearchTree::Search (const int32_t& value)
117 {
118 auto current = root;
119 while (current != nullptr && current->key != value) {
120 current = current->MoveToNextNode (value);
121 }
122 return current;
123 }
124 void BinarySearchTree::Insert (const int32_t& value)
125 {
126 auto result = Search (value);
127 if (result != nullptr) {
128 cerr << "The" << value << "already exist!\n";
129 return;
130 }
131
132 if (root == nullptr) {
133 root = MakeNewNode (value);
134 }
135 else {
136 auto current = root;
137 while (true) {
138 auto& p =
139 current->MoveToNextNode (value);
140 if (p == nullptr) {
141 p = MakeNewNode (value);
142 p->parent = current;
143 break;
144 }
145 current = p;
146 }
147 }
148 }
149 void BinarySearchTree::Delete (const int32_t& value)
150 {
151 auto node = Search (value);
152 if (node == nullptr) {
153 cerr << "There is no such value!\n";
154 return;
155 }
156
157 // Don't have any child.
158 if (node->leftChild == nullptr && node->rightChild == nullptr) {
159 auto parent = (node->parent).lock ();
160 if (IsLeftChild (node)) {
161 parent->leftChild = nullptr;
162 }
163 else {
164 parent->rightChild = nullptr;
165 }
166 }
167
168 // Have double child.
169 else if (node->leftChild != nullptr && node->rightChild != nullptr) {
170 // Find successor
171 auto successor = Successor (node);
172
173 // Delete successor from it's subtree.
174 TransferParent (successor, successor->rightChild);
175
176 // Replace the node.
177 node->key = successor->key;
178 }
179
180 // Have single child.
181 else {
182 if (node->leftChild != nullptr) {
183 TransferParent (node, node->leftChild);
184 }
185 else {
186 TransferParent (node, node->rightChild);
187 }
188 }
189 }