二叉树 遍历c++模板实现

1.结构节点定义
就是左节点 右节点

template<class T>
struct TreeNode {
	TreeNode(T t) {
		value = t;
		left = NULL;
		right = NULL;
	}

	TreeNode() = default;

	T value;
	TreeNode<T>* left;
	TreeNode<T>* right;
};

增加元素的函数 就是看比根节点大还是比根节点小 然后去左右子树



	void Insert(T key) {//这里可以建立线索二叉树  以后再说  下次一定<__<
		TreeNode<T>* pit = root;
		TreeNode<T>* pparent = NULL;

		while (pit) {
			pparent = pit;
			if (pit->value < key) {
				pit = pit->right;
			}
			else if (pit->value > key) {
				pit = pit->left;
			}
			else break;
		}

		pit = new TreeNode<T>(key);
		if (pparent == NULL) {
			root = pit;
		}
		else {
			if (pparent->value < key) {
				pparent->right = pit;
			}
			else if(pparent->value > key){
				pparent->left = pit;
			}
			else {
				delete pit;
			}
		}
	}

层序遍历 便于知道构造了一颗什么树

	void LayerTraverse() {
		TreeNode<T>* pcur = root;
		queue<TreeNode<T>*> m_queue;
		m_queue.push(pcur);
		while (!m_queue.empty()) {
			int size = m_queue.size();
			while (size--) {
				pcur = m_queue.front();
				m_queue.pop();
				if (pcur) {
					cout << pcur->value << " ";
					if (pcur->left)
						m_queue.push(pcur->left);
					else {
						m_queue.push(NULL);
					}
					if (pcur->right) {
						m_queue.push(pcur->right);
					}
					else {
						m_queue.push(NULL);
					}
				}
				else {
					cout << "00 ";
				}
			}
			cout << endl;
		}
	}

删除元素
1.左子树为空 右子树不空 子承父业
2.右空 左不空 子承父业
3.左右都不空 找到前驱或者后继节点 本代码找的前驱 这种情况是左子树的最右节点 因为查找二叉树中序有序 左根右 所以是这个右

	//二叉排序树是中序遍历有序
	//所以删除时需要找到前驱或者后继节点
	void Remove(T key) {
		TreeNode<T>* pcur = root;
		TreeNode<T>* pparent = NULL;
		if (!root)
			return;
		while (pcur) {
			if (pcur->value < key) {
				pparent = pcur;
				pcur = pcur->right;
			}
			else if (pcur->value > key) {
				pparent = pcur;
				pcur = pcur->left;
			}
			else {
				break;
			}
		}

		if (!pcur)
			return;

		// 左子树为空的情况
	   // 待删除结点的右结点"继承"该结点的位置
		if (pcur->left == NULL) {
			if (pparent != NULL) {
				if (pparent->left == pcur) {
					pparent->left = pcur->right;
					delete pcur;
				}
				else {
					pparent->right = pcur->right;
					delete pcur;
				}
			}
			else {
				root = pcur->right;
			}
		}
		else if (!pcur->right) {
			if (pparent != NULL) {
				if (pparent->left == pcur) {
					pparent->left = pcur->left;
					delete pcur;
				}
				else {
					pparent->right = pcur->left;
					delete pcur;
				}
			}
			else {
				root = pcur->left;
			}
		}
		else {
			// 用于替换的结点
			TreeNode<T>* replaceNode = pcur->left;
			// 替换结点的父节点,初始化为待删除的结点
			TreeNode<T>* replaceParentNode = pcur;
			while (replaceNode->right) {
				replaceParentNode = replaceNode;
				replaceNode = replaceNode->right;
			}
			pcur->value = replaceNode->value;
			if (replaceNode == replaceParentNode->left) {
				delete replaceNode;
				replaceNode = nullptr;
				replaceParentNode->left = NULL;
			}
			if (replaceNode == replaceParentNode->right) {
				delete replaceNode;
				replaceNode = nullptr;
				replaceParentNode->right = NULL;
			}
		}
	}

查找元素 没有找到 则加入

	TreeNode<T>* Find(T key) {
		TreeNode<T>* pit = root;
		TreeNode<T>* pparent = NULL;

		while (pit) {
			pparent = pit;
			if (pit->value < key) {
				pit = pit->right;
			}
			else if (pit->value > key) {
				pit = pit->left;
			}
			else if (pit->value == key) {
				return pit;
			}
		}

		pit = new TreeNode<T>(key);
		if (pparent == NULL) {
			root = pit;
		}
		else {
			if (pparent->value < key) {
				pparent->right = pit;
			}
			else if (pparent->value > key) {
				pparent->left = pit;
			}
		}
		return pit;
	}

剩下的是前中后序递归遍历 若要迭代的 请看本人之前一篇博客 树结构

	void PreTraverse(TreeNode<T>* pNode) {
		if (!pNode)
			return;
		cout << pNode->value << " ";
		PreTraverse(pNode->left);
		PreTraverse(pNode->right);
	}

	void PreTraverse() {
		PreTraverse(root);
	}


	void MidTraverse(TreeNode<T>* pNode) {
		if (!pNode)
			return;
		MidTraverse(pNode->left);
		cout << pNode->value << " ";
		MidTraverse(pNode->right);
	}

	void MidTraverse() {
		MidTraverse(root);
	}

	void AfterTraverse(TreeNode<T>* pNode) {
		if (!pNode)
			return;
		AfterTraverse(pNode->left);
		AfterTraverse(pNode->right);
		cout << pNode->value << " ";
	}

	void AfterTraverse() {
		AfterTraverse(root);
	}

完整代码加测试代码

#include <iostream>
#include <queue>

using namespace std;

template<class T>
struct TreeNode {
	TreeNode(T t) {
		value = t;
		left = NULL;
		right = NULL;
	}

	TreeNode() = default;

	T value;
	TreeNode<T>* left;
	TreeNode<T>* right;
};

template<typename T>
class Tree {
public:
	Tree() {

	}

	~Tree() {

	}

	void Insert(T key) {//这里可以建立线索二叉树  以后再说  下次一定<__<
		TreeNode<T>* pit = root;
		TreeNode<T>* pparent = NULL;

		while (pit) {
			pparent = pit;
			if (pit->value < key) {
				pit = pit->right;
			}
			else if (pit->value > key) {
				pit = pit->left;
			}
			else break;
		}

		pit = new TreeNode<T>(key);
		if (pparent == NULL) {
			root = pit;
		}
		else {
			if (pparent->value < key) {
				pparent->right = pit;
			}
			else if(pparent->value > key){
				pparent->left = pit;
			}
			else {
				delete pit;
			}
		}
	}

	void LayerTraverse() {
		TreeNode<T>* pcur = root;
		queue<TreeNode<T>*> m_queue;
		m_queue.push(pcur);
		while (!m_queue.empty()) {
			int size = m_queue.size();
			while (size--) {
				pcur = m_queue.front();
				m_queue.pop();
				if (pcur) {
					cout << pcur->value << " ";
					if (pcur->left)
						m_queue.push(pcur->left);
					else {
						m_queue.push(NULL);
					}
					if (pcur->right) {
						m_queue.push(pcur->right);
					}
					else {
						m_queue.push(NULL);
					}
				}
				else {
					cout << "00 ";
				}
			}
			cout << endl;
		}
	}
	
	//二叉排序树是中序遍历有序
	//所以删除时需要找到前驱或者后继节点
	void Remove(T key) {
		TreeNode<T>* pcur = root;
		TreeNode<T>* pparent = NULL;
		if (!root)
			return;
		while (pcur) {
			if (pcur->value < key) {
				pparent = pcur;
				pcur = pcur->right;
			}
			else if (pcur->value > key) {
				pparent = pcur;
				pcur = pcur->left;
			}
			else {
				break;
			}
		}

		if (!pcur)
			return;

		// 左子树为空的情况
	   // 待删除结点的右结点"继承"该结点的位置
		if (pcur->left == NULL) {
			if (pparent != NULL) {
				if (pparent->left == pcur) {
					pparent->left = pcur->right;
					delete pcur;
				}
				else {
					pparent->right = pcur->right;
					delete pcur;
				}
			}
			else {
				root = pcur->right;
			}
		}
		else if (!pcur->right) {
			if (pparent != NULL) {
				if (pparent->left == pcur) {
					pparent->left = pcur->left;
					delete pcur;
				}
				else {
					pparent->right = pcur->left;
					delete pcur;
				}
			}
			else {
				root = pcur->left;
			}
		}
		else {
			// 用于替换的结点
			TreeNode<T>* replaceNode = pcur->left;
			// 替换结点的父节点,初始化为待删除的结点
			TreeNode<T>* replaceParentNode = pcur;
			while (replaceNode->right) {
				replaceParentNode = replaceNode;
				replaceNode = replaceNode->right;
			}
			pcur->value = replaceNode->value;
			if (replaceNode == replaceParentNode->left) {
				delete replaceNode;
				replaceNode = nullptr;
				replaceParentNode->left = NULL;
			}
			if (replaceNode == replaceParentNode->right) {
				delete replaceNode;
				replaceNode = nullptr;
				replaceParentNode->right = NULL;
			}
		}
	}

	TreeNode<T>* Find(T key) {
		TreeNode<T>* pit = root;
		TreeNode<T>* pparent = NULL;

		while (pit) {
			pparent = pit;
			if (pit->value < key) {
				pit = pit->right;
			}
			else if (pit->value > key) {
				pit = pit->left;
			}
			else if (pit->value == key) {
				return pit;
			}
		}

		pit = new TreeNode<T>(key);
		if (pparent == NULL) {
			root = pit;
		}
		else {
			if (pparent->value < key) {
				pparent->right = pit;
			}
			else if (pparent->value > key) {
				pparent->left = pit;
			}
		}
		return pit;
	}

	void PreTraverse(TreeNode<T>* pNode) {
		if (!pNode)
			return;
		cout << pNode->value << " ";
		PreTraverse(pNode->left);
		PreTraverse(pNode->right);
	}

	void PreTraverse() {
		PreTraverse(root);
	}


	void MidTraverse(TreeNode<T>* pNode) {
		if (!pNode)
			return;
		MidTraverse(pNode->left);
		cout << pNode->value << " ";
		MidTraverse(pNode->right);
	}

	void MidTraverse() {
		MidTraverse(root);
	}

	void AfterTraverse(TreeNode<T>* pNode) {
		if (!pNode)
			return;
		AfterTraverse(pNode->left);
		AfterTraverse(pNode->right);
		cout << pNode->value << " ";
	}

	void AfterTraverse() {
		AfterTraverse(root);
	}
private:
	TreeNode<T>* root;
};


int main(void) {
	Tree<int> t;
	t.Insert(53);
	t.Insert(17);
	t.Insert(78);
	t.Insert(9);
	t.Insert(45);
	t.Insert(65);
	t.Insert(94);
	t.Insert(23);
	t.Insert(81);
	t.Insert(88);
	cout << t.Find(100) << endl;//没有则插入
	t.Remove(53);
	cout << "17  " << t.Find(17) << endl;;
	t.LayerTraverse();
	cout << "pre" << endl;
	t.PreTraverse();
	cout << endl;
	cout << "mid" << endl;
	t.MidTraverse();
	cout << endl;
	cout << "after" << endl;
	t.AfterTraverse();
	cout << endl;
	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值