【c++】二叉搜索树的插入、查找、非递归删除

来源:互联网 发布:淘宝店铺招牌怎么做 编辑:程序博客网 时间:2024/05/29 11:55

尤其注意删除单个根结点、删除有一个分支的根结点时要防止内存泄露(_root为私有成员时)

#include <iostream>#include <stack>#include <queue>using namespace std;//结点类template <class T>class BinaryNode{public:T data;BinaryNode<T> *lchild;BinaryNode<T> *rchild;BinaryNode();BinaryNode(T val);private:};template <class T>BinaryNode<T>::BinaryNode(){data = 0;lchild = NULL;rchild = NULL;}template <class T>BinaryNode<T>::BinaryNode(T val){data = val;lchild = NULL;rchild = NULL;}//二叉树类template <class  T>class BinaryTree{private:BinaryNode<T> *_root;  //根结点public:BinaryTree();//构造空结点BinaryTree(const T preList[], const int size, int index, const T end);//先序构造~BinaryTree();BinaryNode<T>* CreateBiTree(const T preList[], const int size, int &index, const T end);//先序创建二叉树void ClearBiTree(BinaryNode<T> *root);  //销毁二叉树void PreVisitBiTree();//先序遍历,非递归void MidVisitBiTree();//中序遍历,非递归void PostVisitBiTree();//后序遍历,非递归void LevelVisitBiTree();//层序遍历,非递归void InsertTree(int val);void DeleteTree(int val);BinaryNode<T>* SearchTree(int val);};//构造空树template <class T>BinaryTree<T>::BinaryTree(){_root = NULL;}//先序构造二叉树template <class T>BinaryTree<T>::BinaryTree(const T preList[], const int size, int index, const T end){_root = CreateBiTree(preList, size, index, end);}//析构template <class T>BinaryTree<T>::~BinaryTree(){ClearBiTree(_root);_root = NULL;}//先序创建二叉树template <class T>BinaryNode<T>* BinaryTree<T>::CreateBiTree(const T preList[],const int size, int &index,const T end)  //特别注意:index必须用引用,否则函数的两个++index将不会正常改变{BinaryNode<T>* root = NULL;if((index < size) && (preList[index] != end)){root = new BinaryNode<T>();root->data = preList[index];root->lchild = CreateBiTree(preList, size, ++index, end);root->rchild = CreateBiTree(preList, size, ++index, end);}return root;}//销毁二叉树template <class T>void BinaryTree<T>::ClearBiTree(BinaryNode<T>* root){BinaryNode<T> *tmp = root;if(tmp == NULL){return;}ClearBiTree(tmp->lchild);ClearBiTree(tmp->rchild);delete tmp;tmp = NULL;}//非递归遍历//1 前序遍历template <class T>void BinaryTree<T>::PreVisitBiTree(){BinaryNode<T>* cur = _root;stack<BinaryNode<T> *> biTreeStack;if(cur == NULL){cout << "NULL" << endl;return;}while ((cur != NULL) || (!biTreeStack.empty())){while (cur != NULL){cout << cur->data << " "; biTreeStack.push(cur);cur = cur->lchild;}BinaryNode<T> *top = biTreeStack.top();biTreeStack.pop();cur = top->rchild;cur->data;}cout << endl;}//2 中序遍历template<class T>void BinaryTree<T>::MidVisitBiTree(){BinaryNode<T> *cur = _root;stack<BinaryNode<T> *> biTreeStack;while ((cur != NULL) || (!biTreeStack.empty())){while (cur != NULL){biTreeStack.push(cur);cur = cur->lchild;}BinaryNode<T> *top = biTreeStack.top();cout << top->data << " ";biTreeStack.pop();cur = top->rchild;}cout << endl;}//3 后序遍历template<class T>void BinaryTree<T>::PostVisitBiTree(){BinaryNode<T> *cur = _root;BinaryNode<T> *priview = NULL;stack<BinaryNode<T> *> biTreeStack;while ((cur != NULL) || (!biTreeStack.empty())){while (cur != NULL){biTreeStack.push(cur);cur = cur->lchild;}BinaryNode<T> *top = biTreeStack.top();if((top->rchild == NULL) || (priview == top->rchild)){cout << top->data << " ";priview = top;biTreeStack.pop();}else{cur = top->rchild;}}cout << endl;}//4 层序遍历template<class T>void BinaryTree<T>::LevelVisitBiTree(){BinaryNode<T> *cur = _root;queue<BinaryNode<T> *> biTreeQueue;biTreeQueue.push(cur);while (!biTreeQueue.empty()){BinaryNode<T> *top = biTreeQueue.front();cout << top->data << " ";biTreeQueue.pop();if(top->lchild != NULL){biTreeQueue.push(top->lchild);}if(top->rchild != NULL){biTreeQueue.push(top->rchild);}}cout << endl;}//搜索二叉树的插入template<class T>void BinaryTree<T>::InsertTree(int val){if(NULL == _root){_root =new BinaryNode<T>();_root->data = val;return;}BinaryNode<T> *cur = _root;BinaryNode<T> *parant = NULL;BinaryNode<T> *tmp = new BinaryNode<T>();while (cur != NULL){parant = cur;if(val < cur->data){cur = cur->lchild;}else{cur = cur->rchild;}}tmp->data = val;if(val < parant->data){parant->lchild = tmp;}else{parant->rchild = tmp;}}//删除二叉树template<class T>void BinaryTree<T>::DeleteTree(int val){if(NULL == _root){cout << "删除失败:树为空" << endl;return;}BinaryNode<T> *cur = _root;BinaryNode<T> *parent = _root;int flag = 0;while (cur != NULL){if(cur->data == val){if((NULL == cur->lchild) && (NULL == cur->rchild)) //要删除的点为叶节点{if(parent == cur) //树只有一个结点{delete _root;//必须删除原始根结点 _root_root = NULL;return;}else if(parent->lchild == cur) //左孩子为要删除的点{parent->lchild = NULL;}else if(parent->rchild == cur) //右孩子为要删除的点{parent->rchild = NULL;}delete cur;cur = NULL;return;}else if((NULL == cur->lchild) || (NULL == cur->rchild)) //要删除的点有一个孩子{if(parent->lchild == cur)  //要删除的点是左孩子{if(cur->lchild != NULL) //要删除的点有一个左孩子{parent->lchild = cur->lchild;}else if(cur->rchild != NULL){parent->lchild = cur->rchild;}}else if(parent->rchild == cur){if(cur->lchild != NULL){parent->rchild = cur->lchild;}else if(cur->rchild != NULL){parent->rchild = cur->rchild;}}else if(parent == cur)  //要删除的点为根节点,且有一个分支{if(cur->lchild != NULL){_root = cur->lchild;//必须删除原始根结点 _root,如果delete一个局部变量,只是将_root中的值改变,但是//_root还是存在的,它变成了野指针,当再次访问根结点的时候,就会导致内存泄露}else if(cur->rchild != NULL){_root = cur->rchild;//必须删除原始根结点 _root}}delete cur;cur = NULL;return;}else{BinaryNode<T> *tmp = cur;BinaryNode<T> *tmpParent = cur;tmp = tmp->lchild;while (tmp->rchild != NULL){tmpParent = tmp;tmp = tmp->rchild;}cur->data = tmp->data;if(tmpParent == cur){cur->lchild = tmp->lchild;}else{tmpParent->rchild = tmp->lchild;}delete tmp;tmp = NULL;return;}}parent = cur;if(val < cur->data){cur = cur->lchild;}else{cur = cur->rchild;}}cout << "未找到要删除的点" << endl;}//搜索二叉树template<class T>BinaryNode<T>* BinaryTree<T>::SearchTree(int val){if(NULL == _root){cout << "none tree" << endl;return _root;}BinaryNode<T> *cur = _root;while (cur != NULL){if(val < cur->data){cur = cur->lchild;}else if(val > cur->data){cur = cur->rchild;}else{return cur;}}cout << "none tree" << endl;return NULL;}int main(){//int preList[] = {8, 2 , 0, 3, 0, 0, 14, 0, 33, 0, 0};int preList[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};BinaryTree<int> *tree = new BinaryTree<int>(preList, 12, 0, 0);//tree->PreVisitBiTree();//tree->MidVisitBiTree();//tree->PostVisitBiTree();//tree->LevelVisitBiTree();tree->InsertTree(34);tree->InsertTree(32);//tree->InsertTree(33);//tree->DeleteTree(8);tree->DeleteTree(34);//tree->DeleteTree(32);//tree->DeleteTree(33);//tree->DeleteTree(14);//tree->DeleteTree(2);//tree->DeleteTree(3);//tree->DeleteTree(35);cout << "insert a number" << endl;tree->MidVisitBiTree();cout << "search tree" << endl;BinaryNode<int> *tmp = tree->SearchTree(98);if(tmp != NULL){cout << tmp->data << endl;}delete tree;return 0;}


阅读全文
0 0
原创粉丝点击