// DataStructTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <queue>
using namespace std;
enum class NodeTag {
Link,
Thread
};
template <typename Key, typename Value>
class Node
{
public:
Key key;
NodeTag LTag;
NodeTag RTag;
Value value;
Node* leftNode;
Node* rightNode;
Node(Key pKey, Value pValue, Node* pLeftNode, Node* pRightNode)
:key(pKey), value(pValue), leftNode(pLeftNode), rightNode(pRightNode)
{
LTag = NodeTag::Link;
RTag = NodeTag::Link;
}
};
template <typename Key, typename Value>
class BinaryTree
{
private:
Node<Key, Value>* PutNode(Node<Key, Value>* x, Key key, Value value)
{
if (x == nullptr)
{
nodeCnt++;
return new Node<Key, Value>(key, value, nullptr, nullptr);
}
if (key > x->key)
{
x->rightNode = PutNode(x->rightNode, key, value);
}
else if (key < x->key)
{
x->leftNode = PutNode(x->leftNode, key, value);
}
else
{
x->value = value;
}
return x;
}
Node<Key, Value>* DeleteNode(Node<Key, Value>* x, Key key, Node<Key, Value>* delNode)
{
if (x == nullptr)
{
return nullptr;
}
if (key > x->key)
{
x->rightNode = DeleteNode(x->rightNode, key, delNode);
}
else if (key < x->key)
{
x->leftNode = DeleteNode(x->leftNode, key, delNode);
}
else
{
nodeCnt--;
delNode = x;
if (x->rightNode == nullptr)
{
return x->leftNode;
}
if (x->leftNode == nullptr)
{
return x->rightNode;
}
Node<Key, Value>* minNode = x->rightNode;
while (minNode->leftNode != nullptr)
{
minNode = minNode->leftNode;
}
Node<Key, Value>* minNodeTmp = x->rightNode;
while (minNodeTmp->leftNode != nullptr)
{
if (minNodeTmp->leftNode->leftNode == nullptr)
{
minNodeTmp->leftNode = nullptr;
}
else
{
minNodeTmp = minNodeTmp->leftNode;
}
}
minNode->leftNode = x->leftNode;
minNode->rightNode = x->rightNode;
x = minNode;
}
return x;
}
Node<Key, Value>* GetNode(Node<Key, Value>* x, Key key)
{
if (x == nullptr)
{
return nullptr;
}
if (key > x->key)
{
return GetNode(x->rightNode, key);
}
else if (key < x->key)
{
return GetNode(x->leftNode, key);
}
else
{
return x;
}
}
public:
Node<Key, Value>* rootNode;
int nodeCnt;
BinaryTree()
{
rootNode = nullptr;
nodeCnt = 0;
}
~BinaryTree()
{
queue<Node<Key, Value>*>* delNodes = new queue<Node<Key, Value>*>();
Node<Key, Value>* tmpNode = nullptr;
GetNodesMidOrder(rootNode, delNodes);
while (!delNodes->empty())
{
tmpNode = delNodes->front();
delete tmpNode;
tmpNode = nullptr;
delNodes->pop();
}
delete delNodes;
delNodes = nullptr;
nodeCnt = 0;
}
void PutNode(Key key, Value value)
{
rootNode = PutNode(rootNode, key, value);
}
Node<Key, Value>* GetNode(Key key)
{
return GetNode(rootNode, key);
}
void DeleteNode(Key key)
{
Node<Key, Value>* delNode = nullptr;
DeleteNode(rootNode, key, delNode);
delete delNode;
delNode = nullptr;
}
Node<Key, Value>* GetMinNode(Node<Key, Value>* x)
{
if (x->leftNode != nullptr)
{
return GetMinNode(x->leftNode);
}
else
{
return x;
}
}
Node<Key, Value>* GetMaxNode(Node<Key, Value>* x)
{
if (x->rightNode != nullptr)
{
return GetMaxNode(x->rightNode);
}
else
{
return x;
}
}
void GetNodesPreOrder(Node<Key, Value>* x, queue<Node<Key, Value>*>* outNodes)
{
if (x == nullptr)
{
return;
}
outNodes->push(x);
if (x->leftNode != nullptr)
{
GetNodesPreOrder(x->leftNode, outNodes);
}
if (x->rightNode != nullptr)
{
GetNodesPreOrder(x->rightNode, outNodes);
}
}
void GetNodesMidOrder(Node<Key, Value>* x, queue<Node<Key, Value>*>* outNodes)
{
if (x == nullptr)
{
return;
}
if (x->leftNode != nullptr)
{
GetNodesMidOrder(x->leftNode, outNodes);
}
outNodes->push(x);
if (x->rightNode != nullptr)
{
GetNodesMidOrder(x->rightNode, outNodes);
}
}
void GetNodesAftOrder(Node<Key, Value>* x, queue<Node<Key, Value>*>* outNodes)
{
if (x == nullptr)
{
return;
}
if (x->leftNode != nullptr)
{
GetNodesAftOrder(x->leftNode, outNodes);
}
if (x->rightNode != nullptr)
{
GetNodesAftOrder(x->rightNode, outNodes);
}
outNodes->push(x);
}
void GetNodesLayerOrder(Node<Key, Value>* x, queue<Node<Key, Value>*>* outNodes)
{
queue<Node<Key, Value>*>* tmpNodes = new queue<Node<Key, Value>*>();
Node<Key, Value>* n = nullptr;
tmpNodes->push(rootNode);
while (!tmpNodes->empty())
{
n = tmpNodes->front();
tmpNodes->pop();
outNodes->push(n);
if (n->leftNode != nullptr)
{
tmpNodes->push(n->leftNode);
}
if (n->rightNode != nullptr)
{
tmpNodes->push(n->rightNode);
}
}
delete tmpNodes;
tmpNodes = nullptr;
}
int GetMaxDepth(Node<Key, Value>* x)
{
if (x == nullptr)
{
return 0;
}
int maxD = 0;
int maxL = 0;
int maxR = 0;
if (x->leftNode != nullptr)
{
maxL = GetMaxDepth(x->leftNode);
}
if (x->rightNode != nullptr)
{
maxR = GetMaxDepth(x->rightNode);
}
maxD = maxL > maxR ? maxL + 1 : maxR + 1;
return maxD;
}
Node<Key, Value>* pre = NULL;
void TreeThrading(Node<Key,Value>* x)
{
if (x)
{
TreeThrading(x->leftNode);
if (!x->leftNode)
{
x->LTag = NodeTag::Thread;
x->leftNode = pre;
}
if (pre && !pre->rightNode)
{
pre->RTag = NodeTag::Thread;
pre->rightNode = x;
}
pre = x;
TreeThrading(x->rightNode);
}
}
};
int main()
{
BinaryTree<int, string>* bt = new BinaryTree<int, string>();
bt->PutNode(3, "C");
bt->PutNode(1, "A");
bt->PutNode(5, "E");
bt->PutNode(2, "B");
bt->PutNode(4, "D");
bt->TreeThrading(bt->rootNode);
int maxDepth = bt->GetMaxDepth(bt->rootNode);
cout << "maxDepth:" << maxDepth << endl;
bt->DeleteNode(3);
Node<int, string>* minNode = bt->GetMinNode(bt->rootNode);
Node<int, string>* maxNode = bt->GetMaxNode(bt->rootNode);
Node<int, string>* tmpNode = bt->GetNode(4);
cout << "minNode.key:" << minNode->key << endl;
cout << "maxNode.key:" << maxNode->key << endl;
cout << "tmpNode.key:" << tmpNode->key << endl;
cout << "----------------------" << endl;
queue<Node<int, string>*>* qPre = new queue<Node<int, string>*>();
bt->GetNodesPreOrder(bt->rootNode, qPre);
while (!qPre->empty())
{
cout << qPre->front()->key << endl;
qPre->pop();
}
cout << "----------------------" << endl;
queue<Node<int, string>*>* qMid = new queue<Node<int, string>*>();
bt->GetNodesMidOrder(bt->rootNode, qMid);
while (!qMid->empty())
{
cout << qMid->front()->key << endl;
qMid->pop();
}
cout << "----------------------" << endl;
queue<Node<int, string>*>* qAft = new queue<Node<int, string>*>();
bt->GetNodesAftOrder(bt->rootNode, qAft);
while (!qAft->empty())
{
cout << qAft->front()->key << endl;
qAft->pop();
}
cout << "----------------------" << endl;
queue<Node<int, string>*>* qLayer = new queue<Node<int, string>*>();
bt->GetNodesLayerOrder(bt->rootNode, qLayer);
while (!qLayer->empty())
{
cout << qLayer->front()->key << endl;
qLayer->pop();
}
delete bt;
delete qPre;
delete qMid;
delete qAft;
delete qLayer;
cout << "Hello World!\n";
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件