二叉树应用-二叉搜索树类模板的实现(数据结构基础 第6周)
来源:互联网 发布:淘宝商城女装裙子 编辑:程序博客网 时间:2024/05/18 12:43
这里简单实现了二叉搜索树类模板,程序中二叉搜索树继承于二叉树。
该程序仅使用了题目http://dsalgo.openjudge.cn/201409week6/2 进行了简单测试。
源码
//test.cpp
#include <iostream>#include "BinarySearchTree.h"using namespace std;int main() { BinarySearchTree<int> bst; int i; while(cin>>i) { BinaryTreeNode<int> *newpointer=new BinaryTreeNode<int>(i); bst.InsertNode(newpointer); } vector<int> v; v=bst.traversePreOrder(); for (int i=0; i<v.size(); i++) { cout << v.at(i) << ' '; } return 0;}
//BinaryTreeNode.h
#pragma oncetemplate <class T> class BinaryTree;template <class T> class BinarySearchTree;template <class T>class BinaryTreeNode {friend class BinaryTree<T>;friend class BinarySearchTree<T>;private: T element; //二叉树结点数据域 BinaryTreeNode<T>* left; //二叉树结点指向左子树的指针 BinaryTreeNode<T>* right; //二叉树结点指向左子树的指针public: BinaryTreeNode(); BinaryTreeNode(const T& ele); //给定数据的构造函数 BinaryTreeNode(const T& ele,BinaryTreeNode* l, BinaryTreeNode* r);//给定数据的左右指针的构造函数 T value() const; //返回当前结点的数据 BinaryTreeNode<T>& operator= (const BinaryTreeNode<T>& Node) {this=Node;}; //重载赋值操作符 BinaryTreeNode<T>* leftchild() const; //返回当前结点指向左子树的指针 BinaryTreeNode<T>* rightchild() const; //返回当前结点指向右子树的指针 void setLeftchild(BinaryTreeNode<T>*); //设置当前结点的左子树 void setRightchild(BinaryTreeNode<T>*); //设置当前结点的右子树 void setValue(const T& val); //设置当前结点的数据域 bool isLeaf() const; //判定当前结点是否为叶结点,若是返回true};template<class T>BinaryTreeNode<T>::BinaryTreeNode(){ left=right=NULL;}template<class T>BinaryTreeNode<T>::BinaryTreeNode(const T& ele) //给定数据的构造函数{ element=ele; left=right=NULL;}template<class T>BinaryTreeNode<T>::BinaryTreeNode(const T& ele,BinaryTreeNode* l, BinaryTreeNode* r) //给定数据的左右指针的构造函数{ element=ele; left=l; right=r;}template<class T>T BinaryTreeNode<T>::value() const{ return element; }template<class T>BinaryTreeNode<T>* BinaryTreeNode<T>::leftchild() const{ return left; //返回当前结点指向左子树的指针}template<class T>BinaryTreeNode<T>* BinaryTreeNode<T>::rightchild() const{ return right; //返回当前结点指向右子树的指针} template<class T>void BinaryTreeNode<T>::setLeftchild(BinaryTreeNode<T>* subroot)//设置当前结点的左子树{ left=subroot;}template<class T>void BinaryTreeNode<T>::setRightchild(BinaryTreeNode<T>* subroot)//设置当前结点的右子树{ right=subroot;}template<class T>void BinaryTreeNode<T>::setValue(const T& val) //设置当前结点的数据域{ element = val; } template<class T>bool BinaryTreeNode<T>::isLeaf() const //判定当前结点是否为叶结点,若是返回true{ return (left == NULL) && (right == NULL); }
//BinaryTree.h
#pragma once#include "BinaryTreeNode.h"#include <stack>#include <queue>#include <vector>using namespace std;enum Tags{Left,Right};template <class T>class StackElement{public: BinaryTreeNode<T>* pointer; Tags tag;};template <class T>class BinaryTree {protected: BinaryTreeNode<T>* root; //二叉树根结点指针 vector<T> elements; //用于保存遍历的元素private: void Visit(T elem) {elements.push_back(elem);}; //遍历访问元素的值 void PreOrder(BinaryTreeNode<T>* root); //从root前序遍历二叉树或其子树(递归部分) void InOrder(BinaryTreeNode<T>* root); //从root中序遍历二叉树或其子树(递归部分) void PostOrder(BinaryTreeNode<T>* root); //从root后序遍历二叉树或其子树(递归部分) void PreOrderWithoutRecusion(BinaryTreeNode<T>* root); //从root非递归前序遍历二叉树或其子树(递归部分) void InOrderWithoutRecusion(BinaryTreeNode<T>* root); //从root非递归中序遍历二叉树或其子树(递归部分) void PostOrderWithoutRecusion(BinaryTreeNode<T>* root); //从root非递归后序遍历二叉树或其子树 (递归部分) void PostOrderWithoutRecusion2(BinaryTreeNode<T>* root); //从root非递归后序遍历二叉树或其子树, 另一个版本(递归部分) void LevelOrder(BinaryTreeNode<T>* root); //按层次遍历二叉树或其子树protected: BinaryTreeNode<T>* GetParent(BinaryTreeNode<T>* root,BinaryTreeNode<T>* current);//递归由root结点查找current结点的父结点public: BinaryTree(){root=NULL;}; //构造函数 virtual ~BinaryTree(){DeleteBinaryTree(root);}; //析构函数 bool isEmpty() const {return ((root)?TRUE:FALSE);}; //判定二叉树是否为空树 void Initialize(BinaryTreeNode<T>* pointer) {root=pointer;}; BinaryTreeNode<T>* Root() {return root;}; //返回二叉树根节点 BinaryTreeNode<T>* Parent(BinaryTreeNode<T>* current); //返回current结点的父结点指针 BinaryTreeNode<T>* LeftSibling(BinaryTreeNode<T>* current); //返回current结点的左兄弟 BinaryTreeNode<T>* RightSibling(BinaryTreeNode<T>* current);//返回current结点的右兄弟 //以elem作为根结点,leftTree作为树的左子树,rightTree作为树的右子树,构造一棵新的二叉树 void CreateTree(const T& elem, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree); void DeleteBinaryTree(BinaryTreeNode<T>* root); //递归删除二叉树或其子树 vector<T> traversePreOrder(); //从根节点前序遍历,以下依次对应 vector<T> traverseInOrder(); vector<T> traversePostOrder(); vector<T> traversePreOrderWithoutRecusion(); vector<T> traverseInOrderWithoutRecusion(); vector<T> traversePostOrderWithoutRecusion(); vector<T> traversePostOrderWithoutRecusion2(); vector<T> traverseLevelOrder(); };template<class T>BinaryTreeNode<T>* BinaryTree<T>::GetParent(BinaryTreeNode<T>* root,BinaryTreeNode<T>* current){ //从二叉树的root结点开始,查找current结点的父结点 BinaryTreeNode<T>* temp; if(root==NULL) return NULL; //找到父结点 if((root->leftchild()==current)||(root->rightchild()==current)) return root; //递归寻找父结点 if((temp=GetParent(root->leftchild(),current))!=NULL) return temp; else return GetParent(root->rightchild(),current); }template<class T>BinaryTreeNode<T>* BinaryTree<T>::Parent(BinaryTreeNode<T>* current) //返回current结点的父结点指针{ if((current==NULL)||(current==root)) return NULL; //空结点或者current为根结点时,返回NULL return GetParent(root,current); //调用递归函数寻找父结点}template<class T>BinaryTreeNode<T>* BinaryTree<T>::LeftSibling(BinaryTreeNode<T>* current) //返回current结点的左兄弟{ if(current) //current不为空 { BinaryTreeNode<T>* temp=Parent(current); //返回current结点的父结点 if((temp==NULL)||current==temp->leftchild()) return NULL; //如果父结点为空,或者current没有左兄弟 else return temp->leftchild(); } return NULL;}template<class T>BinaryTreeNode<T>* BinaryTree<T>::RightSibling(BinaryTreeNode<T>* current) //返回current结点的右兄弟{ if(current) //current不为空 { BinaryTreeNode<T>* temp=Parent(current);//返回current结点的父结点 if((temp==NULL)||current==temp->rightchild()) return NULL; //如果父结点为空,或者current没有右兄弟 else return temp->rightchild(); } return NULL;}template<class T>void BinaryTree<T>::CreateTree(const T& elem, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree) //以elem作为根结点,leftTree作为树的左子树,rightTree作为树的右子树,构造一棵新的二叉树{ root=new BinaryTreeNode<T>(elem,leftTree.root,rightTree.root); //创建新树 leftTree.root=rightTree.root=NULL; //原来两棵子树的根结点指空,避免访问}template<class T>void BinaryTree<T>::DeleteBinaryTree(BinaryTreeNode<T>* root) //递归删除二叉树或其子树{ if(root) { DeleteBinaryTree(root->left); DeleteBinaryTree(root->right); delete root; };};template<class T>void BinaryTree<T>::PreOrder(BinaryTreeNode<T>* root) //前序遍历二叉树或其子树{ if(root!=NULL) { Visit(root->value()); PreOrder(root->leftchild()); //访问左子树 PreOrder(root->rightchild()); //访问右子树 }};template<class T>vector<T> BinaryTree<T>::traversePreOrder() { elements.clear(); PreOrder(root); return elements;}template<class T>void BinaryTree<T>::InOrder(BinaryTreeNode<T>* root) //中序遍历二叉树或其子树{ if(root!=NULL) { InOrder (root->leftchild()); //访问左子树 Visit(root->value()); //访问当前结点 InOrder (root->rightchild()); //访问右子树 }}template<class T>vector<T> BinaryTree<T>::traverseInOrder() { elements.clear(); InOrder(root); return elements;}template<class T>void BinaryTree<T>::PostOrder(BinaryTreeNode<T>* root) //后序遍历二叉树或其子树{ if(root!=NULL) { PostOrder(root->leftchild()); //访问左子树 PostOrder (root->rightchild()); //访问右子树 Visit(root->value()); //访问当前结点 }}template<class T>vector<T> BinaryTree<T>::traversePostOrder() { elements.clear(); PostOrder(root); return elements;}template<class T>void BinaryTree<T>::PreOrderWithoutRecusion(BinaryTreeNode<T>* root)//非递归前序遍历二叉树或其子树{// using std::stack; stack<BinaryTreeNode<T>* > aStack; BinaryTreeNode<T>* pointer=root; //保存输入参数 while(!aStack.empty()||pointer) { if(pointer){ Visit(pointer->value()); //访问当前结点 aStack.push(pointer); //当前结点地址入栈 pointer=pointer->leftchild(); //当前链接结构指向左孩子 } else { //左子树访问完毕,转向访问右子树 pointer=aStack.top(); //栈顶元素退栈 aStack.pop(); pointer=pointer->rightchild(); //当前链接结构指向右孩子 } //else } //while}template<class T>vector<T> BinaryTree<T>::traversePreOrderWithoutRecusion() { elements.clear(); PreOrderWithoutRecusion(root); return elements;}template<class T>void BinaryTree<T>::InOrderWithoutRecusion(BinaryTreeNode<T>* root) //非递归中序遍历二叉树或其子树{// using std::stack; stack<BinaryTreeNode<T>* > aStack; BinaryTreeNode<T>* pointer=root; //保存输入参数 while(!aStack.empty()||pointer) { if(pointer){ aStack.push(pointer); //当前结点地址入栈 pointer=pointer->leftchild(); //当前链接结构指向左孩子 } else { //左子树访问完毕,转向访问右子树 pointer=aStack.top(); Visit(pointer->value()); //访问当前结点 pointer=pointer->rightchild(); //当前链接结构指向右孩子 aStack.pop(); //栈顶元素退栈 } //else } //while}template<class T>vector<T> BinaryTree<T>::traverseInOrderWithoutRecusion() { elements.clear(); InOrderWithoutRecusion(root); return elements;}template<class T>void BinaryTree<T>::PostOrderWithoutRecusion(BinaryTreeNode<T>* root)//非递归后序遍历二叉树或其子树{// using std::stack; StackElement<T> element; stack<StackElement<T > > aStack; BinaryTreeNode<T>* pointer; if(NULL==root) return; //空树即返回 else pointer=root; while(true) { //进入左子树 while(pointer!=NULL) { element.pointer=pointer; element.tag=Left; aStack.push(element); pointer=pointer->leftchild(); } //托出栈顶元素 element=aStack.top(); aStack.pop(); pointer=element.pointer; //从右子树回来 while(element.tag==Right) { Visit(pointer->value()); //访问当前结点 if(aStack.empty()) return; else { element=aStack.top(); aStack.pop(); pointer=element.pointer; } } //从左子树回来 element.tag=Right; aStack.push(element); pointer=pointer->rightchild(); }}template<class T>vector<T> BinaryTree<T>::traversePostOrderWithoutRecusion() { elements.clear(); PostOrderWithoutRecusion(root); return elements;}template<class T>void BinaryTree<T>::PostOrderWithoutRecusion2(BinaryTreeNode<T>* root){//非递归后序遍历二叉树或其子树, 另一个版本// using std::stack; stack<BinaryTreeNode<T>* > aStack; BinaryTreeNode<T> *p, *q; if(root==NULL) return; p=root; do{ while(p!=NULL) //沿左路分支下降 { aStack.push(p); p=p->leftchild(); } q=NULL; while(!aStack.empty()) { p=aStack.top(); aStack.pop(); if(p->rightchild()==q) //右子树为空或刚刚被访问过 { Visit(p->value()); //访问当前结点 q=p; } else { aStack.push(p); p=p->rightchild(); break; } } }while(!aStack.empty());}template<class T>vector<T> BinaryTree<T>::traversePostOrderWithoutRecusion2() { elements.clear(); PostOrderWithoutRecusion2(root); return elements;}template<class T>void BinaryTree<T>::LevelOrder(BinaryTreeNode<T>* root) //按层次遍历二叉树或其子树,这里使用队列来模拟{// using std::queue; queue<BinaryTreeNode<T>*> aQueue; BinaryTreeNode<T>* pointer=root; if(pointer) aQueue.push(pointer); while(!aQueue.empty()) { pointer=aQueue.front(); Visit(pointer->value()); //访问当前结点 aQueue.pop(); if(pointer->leftchild()) aQueue.push(pointer->leftchild()); if(pointer->rightchild()) aQueue.push(pointer->rightchild()); }}template<class T>vector<T> BinaryTree<T>::traverseLevelOrder() { elements.clear(); LevelOrder(root); return elements;}
//BinarySearchTree.h
#pragma once#include "BinaryTreeNode.h"#include "BinaryTree.h"template <class T>class BinarySearchTree:public BinaryTree<T> {public: BinarySearchTree(){}; virtual ~BinarySearchTree(){}; void InsertNode(BinaryTreeNode<T>* newpointer); void DeleteNode(BinaryTreeNode<T>* pointer);};template <class T>void BinarySearchTree<T>::InsertNode(BinaryTreeNode<T>* newpointer){ BinaryTreeNode<T>* pointer=NULL; //初始化 if(root==NULL) { //用指针newpointer初始化二叉搜索树树根,赋值实现 Initialize(newpointer); return; } else pointer=root; while(1) { if(newpointer->value()==pointer->value()) return ; //相等则不用插入 else if(newpointer->value()<pointer->value()) //作为左子树 { if(pointer->leftchild()==NULL) { pointer->left=newpointer; return; } else pointer=pointer->leftchild(); } else{ //作为右子树 if(pointer->rightchild()==NULL){ pointer->right=newpointer; return; } else pointer=pointer->rightchild(); } }}template <class T>void BinarySearchTree<T>::DeleteNode(BinaryTreeNode<T>* pointer){ if( pointer == NULL ) //如果带删除节点为空,返回 return; BinaryTreeNode<T> * parent = GetParent(root ,pointer ); //保存要删除节点的父节点 if( pointer->leftchild() == NULL ) //如果待删除节点的左子树为空,就将它的右子树代替它即可 { if( parent == NULL ) //将右子树连到待删除节点的父的合适位置 root = pointer->rightchild(); else if( parent->leftchild() == pointer ) parent->left = pointer->rightchild(); else parent->right = pointer->rightchild(); delete pointer; pointer=NULL; return; } //当待删除节点左子树不为空,就在左子树中寻找最大节点替换待删除节点 BinaryTreeNode<T> * temppointer; //保存要替换上来的节点 BinaryTreeNode<T> * tempparent = NULL; //保存要替换上来的节点的父节点 temppointer = pointer->leftchild(); while(temppointer->rightchild() != NULL ) { tempparent = temppointer; temppointer = temppointer->rightchild(); } //删除替换结点 if(tempparent==NULL) pointer->left=temppointer->leftchild(); else tempparent->right=temppointer->leftchild(); //用替换结点去替代真正的删除结点 if(parent==NULL) root=temppointer; else if( parent->leftchild() == pointer ) parent->left=temppointer; else parent->right=temppointer; temppointer->left=pointer->leftchild(); temppointer->right=pointer->rightchild(); delete pointer; pointer=NULL; return;}
0 0
- 二叉树应用-二叉搜索树类模板的实现(数据结构基础 第6周)
- 二叉树应用-Huffman树类模板的实现(数据结构基础 第6周)
- 二叉树应用-最小堆类模板的实现(数据结构基础 第6周)
- 二叉树基础-二叉树类模板的实现(数据结构基础 第5周)
- 二叉树应用-二叉搜索树(数据结构基础 第6周)
- 数据结构基础 之 二叉搜索树的思想与实现
- 【数据结构基础】二叉排序(搜索)树
- 二叉树应用-Huffman编码树(数据结构基础 第6周)
- 二叉树应用-表达式·表达式树·表达式求值(数据结构基础 第6周)
- 数据结构-二叉搜索树的实现
- 数据结构 二叉搜索树实现
- 【数据结构】第4周 二叉树基础
- 第4章 树 - 二叉搜索树数据结构实现
- 【C基础】二叉搜索树的实现
- 数据结构--二叉搜索树的实现(C++)
- 二叉搜索树的实现(数据结构中的“hello,world”)
- 二叉树基础-实现堆结构(数据结构基础 第5周)
- C++实现二叉搜索树(二叉排序树)模板类
- 微服务:ICE 入门之 编译环境搭建
- 又是文件中的不可见字符问题
- 【MyBatis框架】查询缓存-二级缓存-整合ehcache
- hdu_tian_Ji_The_hourse_Racing
- Irrlicht引擎学习笔记(13)--LoadIrrFile
- 二叉树应用-二叉搜索树类模板的实现(数据结构基础 第6周)
- poj 1363
- C++11并发编程实战
- matlab在图片上画标记然后整幅保存的方法
- 用两个遍历建树——树的遍历、玩转二叉树
- Repeater控件绑定及分页
- ContentPrivider内容提供者
- Linux系统调用--getrlimit()与setrlimit()函数详解
- Linux(CentOS)挂载U盘、移动硬盘以及文件拷贝、备份