二叉树未完待续

// 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 文件

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值