二叉树的相关操作(大集合)
自己的第一篇博客,有点小激动~
这段时间学习二叉树,敲了看了不少代码,贴出来。由于个人水平有限,希望大家不吝赐教。
vc6.0调试通过
#include <iostream> #include <queue> #include <stack> using namespace std; template <class T> class Node{ public: T element; //数据 Node <T>* leftChild; //左孩子结点 Node <T>* rightChild; //右孩子结点 public: Node(){ element = 0; leftChild = rightChild = NULL; } Node(T el,Node<T> *l,Node<T> *r){ element = el; leftChild = l; rightChild = r; } ~Node(){} //默认析构 void setLeftChild(Node<T>* l); //设置左孩子结点 void setRightChild(Node<T>* r); //设置右孩子结点 void setValue(const T& val); // 设置该结点数据 T getvalue() const; //返回该结点的数据 bool isLeaf() const; //判断该节点是否是叶子结点 }; template <class T> void Node<T>::setValue(const T& val) { element = val; } template <class T> bool Node<T>::isLeaf() const { if (leftChild == NULL && rightChild == NULL) return 1; else return 0; } template <class T> T Node<T>::getvalue() const { return element; } template <class T> void Node<T>::setLeftChild(Node<T>* l) { leftChild = l; } template <class T> void Node<T>::setRightChild(Node<T>* r) { rightChild = r; } //二叉树类 template <class T> class Tree { public: Node <T>* root; public: Tree();//默认构造 ~Tree(); //析构 friend Node<T> *makeTree(Node <T>* root); //建立树 ______/////////////////////// bool isEmpty() const; //判断二叉树是否为空 Node<T> * getRoot() const; //返回二叉树的根节点 void del(Node<T>* r); void preOrder(Node<T>* root);//前序优先遍历 void inOrder(Node<T>* root);//中序遍历 void postOrder(Node<T>* root);//后序优先遍历 friend void levelOrder();//广度优先遍历 void preOrder();//前序优先遍历(非递归) void inOrder();//中序优先遍历(非递归) void postOrder();//后序优先遍历(非递归) void NodeCount(Node<T>* root);//求度为特定值的结点个数 int High(Node<T>* root,int high);//求树的高度 int MaxValue(Node<T>* root);//求最大的结点 void Exchang(Node<T>* root);//交换每个结点的左孩子结点和右孩子结点 void DelLeaf(Node<T>* root);//删除所有叶子结点 int Width(Node<T>* root);//递归求二叉树的宽度 bool JudgeComplete(Node<T>* root);//判断该二叉树是否为完全二叉树 }; template <class T> Node<T> * Tree<T>::getRoot() const { return root; } template <class T> bool Tree<T>::isEmpty() const { if (root == NULL) return 1; else return 0; } template <class T> Tree<T>::Tree() { root = NULL; } template <class T> Tree<T>::~Tree() //析构函数有问题 { Node <T>* temp; temp = root; if (temp != 0) { del(temp->leftChild); del(temp->rightChild); } } template <class T> void Tree<T>::del(Node<T>* r) { delete r; } template <class T> Node <T>* makeTree(Node <T>* root) // 递归 建立树 ////////////////////////////// { // if (root) // root = new Node(el,left.root,right.root); // left.root = right.root = NULL; T te; cin>>te; if (te != -1) { root = new Node<T>; root->element = te; // cout<<root->element<<"的左子树"<<endl; cout<<"输入"<<root->element<<"的左孩子"<<endl; root->leftChild = makeTree(root->leftChild); // cout<<root->element<<"的右子树"<<endl; cout<<"输入"<<root->element<<"的右孩子"<<endl; root->rightChild = makeTree(root->rightChild); } else { // cout<<root<<endl; root = NULL; } return root; } template<class T> bool Tree<T>::JudgeComplete(Node<T>* root) //判断是否为完全二叉树 { queue<Node<T> *> nodeQueue; Node <T>* pointer = root; if(pointer) nodeQueue.push(pointer); while (!nodeQueue.empty()) { pointer = nodeQueue.front(); // cout<<pointer->element<<" "; if (pointer == NULL) break; nodeQueue.pop(); nodeQueue.push(pointer->leftChild); nodeQueue.push(pointer->rightChild); } while (!nodeQueue.empty()) { pointer = nodeQueue.front(); if (pointer != NULL) return 0; nodeQueue.pop(); } return 1; } //统计二叉树的宽度 template<class T> int Tree<T>::Width(Node<T>* root) { int l = 0; int r = 0; if (root) { if (root->leftChild == NULL && root->rightChild == NULL) return 1; else { if (root->leftChild != NULL) l = Width(root->leftChild); if (root->rightChild != NULL) r = Width(root->rightChild); } } return l+r; } //删除所有叶子结点 Node<int>* temp; template<class T> void Tree<T>::DelLeaf(Node<T>* root) { if (root) { if (root->leftChild == NULL && root->rightChild == NULL) { if (temp->leftChild == root) { temp->leftChild = NULL; delete root; root = NULL; } else if (temp->rightChild == root) { temp->rightChild = NULL; delete root; root = NULL; } } if (root) { temp = root; DelLeaf(root->leftChild); DelLeaf(root->rightChild); } } } //交换每个结点的左孩子结点和右孩子结点 template<class T> void Tree<T>::Exchang(Node<T>* root) { Node<T>* p; //temp if (root) { /* if (root->leftChild == NULL) root->leftChild = root->rightChild; else if (root->rightChild == NULL) root->rightChild = root->leftChild;*/ // else // { p = root->leftChild; root->leftChild = root->rightChild; root->rightChild = p; // } Exchang(root->leftChild); Exchang(root->rightChild); } } //求最大值的元素 template<class T> int Tree<T>::MaxValue(Node<T>* root) { int a; if (root) { if (root->leftChild == NULL && root->rightChild == NULL) return root->element; else if (root->leftChild == NULL) { if (root->element >= MaxValue(root->rightChild)) return root->element; else return MaxValue(root->rightChild); } else if (root->rightChild == NULL) { if (root->element >= MaxValue(root->leftChild)) return root->element; else return MaxValue(root->leftChild); } else { if (root->element >= MaxValue(root->leftChild)) a = root->element; else //(root->element < MaxValue(root->leftChild)) a = MaxValue(root->leftChild); if (a >= MaxValue(root->rightChild)) return a; else return MaxValue(root->rightChild); } } // if (root->leftChild == NULL && root->rightChild == NULL) // return root->element; } //计算特定度的结点个数 int count0 = 0; int count1 = 0; int count2 = 0; template<class T> void Tree<T>::NodeCount(Node<T>* root) { if (root) { NodeCount(root->leftChild); if (root->leftChild == NULL && root->rightChild == NULL) count0++; if ((root->leftChild == NULL && root->rightChild != NULL) || (root->leftChild != NULL && root->rightChild == NULL)) count1++; if (root->leftChild != NULL && root->rightChild != NULL) count2++; NodeCount(root->rightChild); } } template<class T> int Tree<T>::High(Node<T>* root,int high) //求树的高度 { if (root) { if (root->leftChild == NULL && root->rightChild == NULL) high = 0; else { if (High(root->leftChild,high) >= High(root->rightChild,high)) high += High(root->leftChild,high); else high += High(root->rightChild,high); } } return high; } //广度优先遍历 template <class T> void levelOrder(Node <T>* root) { queue<Node<T> *> nodeQueue; Node <T>* pointer = root; cout<<"=====广度优先遍历====="<<endl; if(pointer) nodeQueue.push(pointer); while (!nodeQueue.empty()) { pointer = nodeQueue.front(); cout<<pointer->element<<" "; nodeQueue.pop(); if (pointer->leftChild) nodeQueue.push(pointer->leftChild); if (pointer->rightChild) nodeQueue.push(pointer->rightChild); } } //前序遍历 template <class T> void Tree<T>::preOrder(Node<T>* root) { //cout<<"======前序遍历======"; if (root != NULL) { cout<<root->element<<" "; preOrder(root->leftChild); preOrder(root->rightChild); } } //中序遍历 template <class T> void Tree<T>::inOrder(Node<T>* root) { if (root != NULL) { inOrder(root->leftChild); cout<<root->element<<" "; inOrder(root->rightChild); } } //后序遍历 template <class T> void Tree<T>::postOrder(Node<T>* root) { if (root != NULL) { postOrder(root->leftChild); postOrder(root->rightChild); cout<<root->element<<" "; } } template <class T> void Tree<T>::preOrder() //前序遍历二叉树(非递归形式) { stack<Node<T> *> nodestack; Node <T>* pointer = root; //保存根节点 cout<<"========前序遍历二叉树(非递归)========="<<endl; while(!nodestack.empty() || pointer) { if (pointer){ cout<<pointer->element<<" "; if (pointer->rightChild != NULL) nodestack.push(pointer->rightChild); pointer = pointer->leftChild; } else { pointer = nodestack.top(); nodestack.pop(); } } } template <class T> void Tree<T>::inOrder() //中序遍历二叉树(非递归形式 ) { stack<Node<T> *> nodestack; Node <T>* pointer = root;//保存根节点 cout<<"========中序遍历二叉树(非递归)========="<<endl; while (!nodestack.empty() || pointer) { if (pointer){ nodestack.push(pointer); // cout<<pointer->element<<" "; pointer = pointer->leftChild; } else { pointer = nodestack.top(); cout<<pointer->element<<" "; pointer = pointer->rightChild; nodestack.pop(); } } } template <class T> /*void Tree<T>::postOrder()//后序优先遍历(非递归) { stack<Node<T> *> nodestack; Node <T>* pointer = root; int temp = 0; int s = 0; while (!nodestack.empty() || pointer) { if (pointer && s == 0){ nodestack.push(pointer); pointer = pointer->leftChild; temp = 0; s = 0; } else if (pointer && s == 1) { pointer = nodestack.top(); nodestack.pop(); } else if(temp == 0) { temp = 1; pointer = nodestack.top(); pointer = pointer->rightChild; // nodestack.pop(); } else { cout<<pointer->element<<" "; pointer = nodestack.top(); nodestack.pop(); s = 1; } } }*/ void Tree<T>::postOrder() //后序优先遍历 { stack<Node <T>*> nodestack; Node <T>* pointer = root; Node <T>* pre = root;//保存前一个被访问的结点 cout<<"========后序遍历二叉树(非递归)========="<<endl; while (pointer) { for (;pointer->leftChild != NULL;pointer = pointer->leftChild) nodestack.push(pointer);//将所有左孩子结点压栈 while (pointer != NULL && (pointer->rightChild == NULL || pointer->rightChild == pre)){ cout<<pointer->element<<" "; pre = pointer; if (nodestack.empty()) return; pointer = nodestack.top();// nodestack.pop(); } nodestack.push(pointer); pointer = pointer->rightChild; //转向右子树 } } int main() { Tree<int> t; t.root = makeTree(t.root); /* // cout<<t.getRoot(); levelOrder(t.root); cout<<endl<<"======前序遍历======"<<endl; t.preOrder(t.root); cout<<endl<<"======中序遍历======"<<endl; t.inOrder(t.root); cout<<endl<<"======后序遍历======"<<endl; t.postOrder(t.root); cout<<endl; t.preOrder(); cout<<endl; t.inOrder(); cout<<endl; t.postOrder(); */ t.NodeCount(t.root); //计算度为0,1,2的结点的个数 cout<<"度为0的结点的个数为:"<<count0<<endl<<"度为1的结点的个数为:"<<count1<<endl<<"度为2的结点的个数为:"<<count2<<endl; cout<<"该二叉树的高度为:"<<t.High(t.root,1)<<endl; cout<<"该二叉树的最大元素的值为:"<<t.MaxValue(t.root)<<endl; /* t.Exchang(t.root); cout<<"每个结点的左孩子结点和右孩子结点都已经交换"<<endl; t.preOrder(); t.DelLeaf(t.root); cout<<"删除叶子结点后的结果:"<<endl; t.preOrder(); cout<<"该二叉树的宽度为:"<<t.Width(t.root)<<endl; */ if (t.JudgeComplete(t.root)) cout<<"该二叉树是完全二叉树"; else cout<<"该二叉树不是完全二叉树"; return 0; }