赞
踩
目录
前言
个人认为二叉树的核心是递归,绝大部分的操作,都可以使用递归来实现。
主要操作
- template <class T>
- struct BinTreeNode{
- T data;
- BinTreeNode *leftChild,*rightChild;
- BinTreeNode():leftChild(NULL),rightChild(NULL){}
- BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL)
- :data(x),leftChild(l),rightChild(r){}
- };
-
- //类定义
- //对象: 结点的有限集合, 二叉树是有序树
- template <class T>
- class BinaryTree {
-
- public:
- //构造函数
- BinaryTree ():root(NULL){}
- BinaryTree(T value):RefValue(value),root(NULL){}
- BinaryTree(BinaryTree<T>& s);
- ~BinaryTree(){destroy(root);}
- BinaryTree (BinTreeNode<T> *lch,BinTreeNode<T> *rch, T item);
- //构造函数, 以item为根, lch和rch为左、右子
-
-
- //树构造一棵二叉树
- //BinTreeNode<T> *createpretree(int l,int i,string &a);
- void CreatTree(BinTreeNode<T> *& root);
-
- //高度、深度、判空、取结点
- int Height (BinTreeNode<T> * root);//求树深度或高度{return Height(root);}
- int Size (BinTreeNode<T> * root);//求树中结点个数{return Size(root);}
- bool IsEmpty (){return (root==NULL)?true:false;}; //判二叉树空否?
- bool Find (T& item,BinTreeNode<T> * root); //判断item是否在树中
- BinTreeNode<T> *getData(T& item,BinTreeNode<T> * root); //取得结点数据
-
- //求结点
- BinTreeNode<T> *Parent (BinTreeNode <T> *subTree,BinTreeNode<T> *t);
- //求结点 t 的双亲{return (root==NULL||root==t)?NULL:Parent(root,t);}
- BinTreeNode<T> *LeftChild (BinTreeNode<T> *t)//求结点 t 的左子女
- {return (t!=NULL)?t->leftChild:NULL;}
- BinTreeNode<T> *RightChild (BinTreeNode<T> *t)//求结点 t 的右子女
- {return (t!=NULL)?t->rightChild:NULL;}
-
-
- //遍历
- BinTreeNode<T> *getRoot (){return root;} //取根
- BinTreeNode<T> *CopyTree( BinTreeNode<T> *orignode);
- void preOrder ( BinTreeNode<T> *root);//前序遍历
-
- void inOrder ( BinTreeNode<T> * root);//中序遍历
-
- void postOrder ( BinTreeNode<T> * root);//后序遍历
-
- void levelOrder (BinTreeNode<T> * root);//层次序遍历
-
-
- protected:
- BinTreeNode<T> * root;
- T RefValue;
- void destroy (BinTreeNode<T> * subTree);
-
- };
空传入
- template <class T>
- void BinaryTree<T>::CreatTree(BinTreeNode<T> *& root)
- { T item;
- cin>>item;
- if(item!=RefValue)
- { root=new BinTreeNode<T>(item);
- if(root ==NULL)
- { cerr<<"分配结点失败!\n"; exit(1); }
- CreatTree(root->leftChild);
- CreatTree(root->rightChild);
- }
- else root=NULL;
- }
传引用
- template <class T>
- BinTreeNode<T> * BinaryTree<T>::createpretree(int l,int i,string &a)
- {//l为数组a的长度,i为数组下标
- BinTreeNode<T> *root;
- if(l==0||a[i]=='#'||i==l)root=NULL;
- else
- {
- root=new BinTreeNode<T>(a[i++]);
- root->leftChild=createpretree(l,i,a);
- root->rightChild=createpretree(l,++i,a);
- }
- return root;
- }
- template <class T>
- void BinaryTree<T>::preOrder(BinTreeNode<T> * root)
- {
- if (root != NULL)
- {
- cout<<root->data<<" "; //先序访问根结点
- preOrder(root->leftChild); //遍历左子树
- preOrder(root->rightChild); //先序遍历右子树
- }
- }
- template <class T>
- void BinaryTree<T>::inOrder(BinTreeNode<T> * root)
- {
- if (root != NULL)
- {
- inOrder(root->leftChild); //中序遍历左子树
- cout<<root->data<<" "; //访问根结点
- inOrder(root->rightChild); //中序遍历右子树
- }
- }
- template <class T>
- void BinaryTree<T>::postOrder(BinTreeNode<T> * root)
- {
- if (root != NULL)
- {
- postOrder(root->leftChild); //后序遍历左子树
- postOrder(root->rightChild); //遍历右子树
- cout<<root->data<<" "; //后序访问根结点
- }
- }
- template <class T>
- void BinaryTree<T>::levelOrder(BinTreeNode<T> *root)
- { if (root == NULL) return;
- queue<BinTreeNode<T> * > Q;
- BinTreeNode<T> *p;
- Q.push(root); //根结点入队列
- while (!Q.empty())
- {
- p=Q.front();
- cout<<(Q.front())->data<<" "; //输出出队结点的数据
- Q.pop(); //队头结点出队
- if (p->leftChild != NULL) //若出队结点有左孩子
- { Q.push(p->leftChild);} //左孩子入队列p=p->leftChild;
- if (p->rightChild != NULL)
- {Q.push(p->rightChild);
- }
- }
- }
有一种方法是使用自定义的队列,思路大致和上面相同,但在此不写怎么麻烦的方法了。
- template <class T>
- BinTreeNode<T> *BinaryTree<T>::
- Parent (BinTreeNode <T> *subTree,BinTreeNode <T> *t)
- {
- if (subTree == NULL) return NULL;
- if (subTree->leftChild == t ||subTree->rightChild == t)
- return subTree; //找到, 返回父结点地址
- BinTreeNode <T> *p;
- if ((p = Parent (subTree->leftChild, t)) != NULL)
- return p; //递归在左子树中搜索
- else return Parent (subTree->rightChild, t);
- //递归在右子树中搜索
- }
- //定义在类中
- BinTreeNode<T> *LeftChild (BinTreeNode<T> *t)
- {return (t!=NULL)?t->leftChild:NULL;}//求结点 t 的左子女
-
- BinTreeNode<T> *RightChild (BinTreeNode<T> *t)
- {return (t!=NULL)?t->rightChild:NULL;} //求结点 t 的右子女
- template <class T>
- int BinaryTree<T>::Height(BinTreeNode<T> * root)
- {
- if (root == NULL) return 0;
- else
- {
- int i = Height(root->leftChild);
- int j = Height(root->rightChild);
- return (i < j) ? j+1 : i+1;
- }
- }
- template <class T>
- int BinaryTree<T>::Size(BinTreeNode<T> * root)
- {
- if (root == NULL) return 0; //空树
- else
- return 1+Size(root->leftChild)+Size(root->rightChild);
- }
- //在类中
- bool IsEmpty (){return (root==NULL)?true:false;};
- template<class T>
- bool BinaryTree<T>::Find (T& item,BinTreeNode<T> * root)
- {
- if(this->getData(item,root)==NULL)return false;
- else return true;
- }
- template<class T>
- BinTreeNode<T> *BinaryTree<T>::getData(T& item,BinTreeNode<T> * root)
- {
- if(root==NULL)return NULL;
- if(root->data==item)return root;
- return getData(item,root->leftChild)!=NULL?getData(item,root->leftChild):getData(item,root->rightChild);
-
- }
- template<class T>
- void BinaryTree<T>::destroy (BinTreeNode<T>* subTree) {
- //私有函数: 后序遍历删除根为subTree的子树;
- if (subTree != NULL) {
- destroy (subTree->leftChild); //删除左子树
- destroy (subTree->rightChild); //删除右子树
- delete subTree; //删除根结点
- }
- }
- int main()
- {
-
- char ch;
- cout<<"输入结束标志:";
- cin>>ch;
- BinaryTree<char> t(ch);
- BinTreeNode<char>* head=t.getRoot();
- t.CreatTree(head);
- return 0;
- }
- #include<bits/stdc++.h>
- using namespace std;
- template <class T>
- struct BinTreeNode{
- T data;
- BinTreeNode *leftChild,*rightChild;
- BinTreeNode():leftChild(NULL),rightChild(NULL){}
- BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL)
- :data(x),leftChild(l),rightChild(r){}
- };
-
- //类定义
- //对象: 结点的有限集合, 二叉树是有序树
- template <class T>
- class BinaryTree {
-
- public:
- BinaryTree ():root(NULL){} //构造函数
- BinaryTree(T value):RefValue(value),root(NULL){}
- BinaryTree(BinaryTree<T>& s);
- ~BinaryTree(){destroy(root);}
- BinaryTree (BinTreeNode<T> *lch,BinTreeNode<T> *rch, T item);
- //构造函数, 以item为根, lch和rch为左、右子
- //树构造一棵二叉树
- //BinTreeNode<T> *createpretree(int l,int i,string &a);
- void CreatTree(BinTreeNode<T> *& root);
- int Height (BinTreeNode<T> * root);//求树深度或高度{return Height(root);}
- int Size (BinTreeNode<T> * root);//求树中结点个数{return Size(root);}
- bool IsEmpty (){return (root==NULL)?true:false;}; //判二叉树空否?
-
- BinTreeNode<T> *Parent (BinTreeNode <T> *subTree,BinTreeNode<T> *t);
- //求结点 t 的双亲{return (root==NULL||root==t)?NULL:Parent(root,t);}
-
- BinTreeNode<T> *LeftChild (BinTreeNode<T> *t)
- {return (t!=NULL)?t->leftChild:NULL;}//求结点 t 的左子女
-
- BinTreeNode<T> *RightChild (BinTreeNode<T> *t)
- {return (t!=NULL)?t->rightChild:NULL;} //求结点 t 的右子女
-
- //bool Insert (const T& item); //在树中插入新元素
- //bool Remove (T item); //在树中删除元素
- bool Find (T& item,BinTreeNode<T> * root); //判断item是否在树中
- BinTreeNode<T> *getData(T& item,BinTreeNode<T> * root); //取得结点数据
- BinTreeNode<T> *getRoot (){return root;} //取根
- BinTreeNode<T> *CopyTree( BinTreeNode<T> *orignode);
- void preOrder ( BinTreeNode<T> *root);//前序遍历
-
- void inOrder ( BinTreeNode<T> * root);//中序遍历
-
- void postOrder ( BinTreeNode<T> * root);//后序遍历
-
- void levelOrder (BinTreeNode<T> * root);//层次序遍历
-
-
- protected:
- BinTreeNode<T> * root;
- T RefValue;
- void destroy (BinTreeNode<T> * subTree);
-
- };
-
- //template <class T>
- //BinaryTree::BinaryTree()
- /*
- //建立二叉树
- template <class T>
- BinTreeNode<T> * BinaryTree<T>::createpretree(int l,int i,string &a)
- {
- BinTreeNode<T> *root;
- if(l==0||a[i]=='#'||i==l)root=NULL;
- else
- {
- root=new BinTreeNode<T>(a[i++]);
- root->leftChild=createpretree(l,i,a);
- root->rightChild=createpretree(l,++i,a);
- }
- return root;
- }*/
-
- //先序遍历创建一棵二叉树
- template <class T>
- void BinaryTree<T>::CreatTree(BinTreeNode<T> *& root)
- { T item;
- cin>>item;
- if(item!=RefValue)
- { root=new BinTreeNode<T>(item);
- if(root ==NULL)
- { cerr<<"分配结点失败!\n"; exit(1); }
- CreatTree(root->leftChild);
- CreatTree(root->rightChild);
- }
- else root=NULL;
- }
-
- //遍历
- //先序遍历
- template <class T>
- void BinaryTree<T>::preOrder(BinTreeNode<T> * root)
- {
- if (root != NULL)
- { cout<<root->data<<" "; //先序访问根结点
- preOrder(root->leftChild); //遍历左子树
- preOrder(root->rightChild); //先序遍历右子树
- }
- }
-
- //中序遍历
- template <class T>
- void BinaryTree<T>::inOrder(BinTreeNode<T> * root)
- {
- if (root != NULL)
- {
- inOrder(root->leftChild); //中序遍历左子树
- cout<<root->data<<" "; //访问根结点
- inOrder(root->rightChild); //中序遍历右子树
- }
- }
-
- //后序遍历
- template <class T>
- void BinaryTree<T>::postOrder(BinTreeNode<T> * root)
- {
- if (root != NULL)
- {
- postOrder(root->leftChild); //后序遍历左子树
- postOrder(root->rightChild); //遍历右子树
- cout<<root->data<<" "; //后序访问根结点
- }
- }
-
- //层次遍历
- template <class T>
- void BinaryTree<T>::levelOrder(BinTreeNode<T> *root)
- { if (root == NULL) return;
- queue<BinTreeNode<T> * > Q;
- BinTreeNode<T> *p;
- Q.push(root); //根结点入队列
- while (!Q.empty())
- {
- p=Q.front();
- cout<<(Q.front())->data<<" "; //输出出队结点的数据
- Q.pop(); //队头结点出队
- if (p->leftChild != NULL) //若出队结点有左孩子
- { Q.push(p->leftChild);} //左孩子入队列p=p->leftChild;
- if (p->rightChild != NULL)
- {Q.push(p->rightChild);
- }
- }
- }
- //结点个数
- template <class T>
- int BinaryTree<T>::Size(BinTreeNode<T> * root)
- {
- if (root == NULL) return 0; //空树
- else
- return 1+Size(root->leftChild)+Size(root->rightChild);
- }
-
- //空树高度为0
- template <class T>
- int BinaryTree<T>::Height(BinTreeNode<T> * root)
- {
- if (root == NULL) return 0;
- else
- {
- int i = Height(root->leftChild);
- int j = Height(root->rightChild);
- return (i < j) ? j+1 : i+1;
- }
- }
-
- //二叉树复制
- template <class T>
- BinTreeNode<T> * BinaryTree<T>::CopyTree( BinTreeNode<T> *orignode)
- {
- if(orignode==NULL) return NULL;
- BinTreeNode<T> *temp=new BinTreeNode<T>;
- temp->data=orignode->data;
- temp->leftChild=CopyTree(orignode->leftChild);
- temp->rightChild=CopyTree(orignode->rightChild);
- return temp;
- }
-
- //寻找双亲结点
- template <class T>
- BinTreeNode<T> *BinaryTree<T>::
- Parent (BinTreeNode <T> *subTree,BinTreeNode <T> *t)
- {
- if (subTree == NULL) return NULL;
- if (subTree->leftChild == t ||subTree->rightChild == t)
- return subTree; //找到, 返回父结点地址
- BinTreeNode <T> *p;
- if ((p = Parent (subTree->leftChild, t)) != NULL)
- return p; //递归在左子树中搜索
- else return Parent (subTree->rightChild, t);
- //递归在右子树中搜索
- }
-
-
- //查找结点数据
- template<class T>
- BinTreeNode<T> *BinaryTree<T>::getData(T& item,BinTreeNode<T> * root)
- {
- if(root==NULL)return NULL;
- if(root->data==item)return root;
- return getData(item,root->leftChild)!=NULL?getData(item,root->leftChild):getData(item,root->rightChild);
-
- }
-
- //查找结点是否在树中
- template<class T>
- bool BinaryTree<T>::Find (T& item,BinTreeNode<T> * root)
- {
- if(this->getData(item,root)==NULL)return false;
- else return true;
- }
-
-
- //销毁二叉树
- template<class T>
- void BinaryTree<T>::destroy (BinTreeNode<T>* subTree) {
- //私有函数: 后序遍历删除根为subTree的子树;
- if (subTree != NULL) {
- destroy (subTree->leftChild); //删除左子树
- destroy (subTree->rightChild); //删除右子树
- delete subTree; //删除根结点
- }
- }
-
-
- //BinTreeNode<char> *root;
- int main()
- {
-
- char ch;
- cout<<"输入结束标志:";
- cin>>ch;
- BinaryTree<char> t(ch);
- // cout<<"输入遍历序列:";
- // string a;
- // cin>>a;
- // int l=a.length();
- // int i=0;
- BinTreeNode<char>* head=t.getRoot();
- t.CreatTree(head);
-
- return 0;
- }
点个赞再走吧~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。