包括二分搜索树的创建,插入,删除,前序、中序、后序、广度以及深度的递归和递归算法,获取二叉树最小节点,最大节点,获取当前节点的后序或者前序节点,对二叉树的搜索判定:
template<typename T> class treenode{ public: T ele; treenode<T>*left; treenode<T>*right; treenode(){left=NULL; right=NULL;} treenode(T ele){ this->ele=ele; left=NULL; right=NULL;} }; template<typename T> class bitree{ private:treenode<T>*root; int size; void inorder(treenode<T>*root); void preorder(treenode<T>*root); void postorder(treenode<T>*root); public: bitree(){root=NULL;size=0;} bitree(T ele[],int size); bool insert(T ele); void inorder(); void preorder(); void postorder(); // 获取二叉树的最小关键字节点 treenode<T>*getmin(treenode<T>*root){ treenode<T>*pa=NULL; if (root==NULL)return NULL; else{ while(root!=NULL){pa=root; root=root->left;} return pa;} } // 获取二叉树的最大关键字节点 treenode<T>*getmax(treenode<T>*root1){ treenode<T>*pa=NULL; if (root1==NULL)return NULL; else{ while(root1!=NULL){pa=root1; root1=root1->right;} return pa;} } // 获取给定节点在中序遍历下的后续节点 treenode<T>*getafter(treenode<T>*p){ if(p==NULL) return NULL; else{// 分两种情况考虑,此节点是否有右子树 // 当这个节点有右子树的情况下,那么右子树的最小关键字节点就是这个节点的后续节点 if(p->right!=NULL) return getmin(p->right); // 当这个节点没有右子树的情况下, // 如果这个节点的父节点的左子树 与 这个节点相同的话,那么就说明这个父节点就是后续节点了 treenode<T>*parent=getparent(p); //while(parent!=NULL&&parent->right==p){ //p=parent; //parent=getparent(parent);} return parent; }} // 获取给定节点在中序遍历下的前趋结点 treenode<T>*getbefore(treenode<T>*p){ if(p==NULL) return NULL; else{// 分两种情况考虑,此节点是否有左子树 // 当这个节点有右子树的情况下,那么右子树的最小关键字节点就是这个节点的后续节点 if(p->left!=NULL) return getmax(p->left); // 当这个节点没有左子树的情况下, // 那么就说明这个父节点就是后续节点了 treenode<T>*parent=getparent(p); while(parent!=NULL&&parent->right==p){ p=parent; parent=getparent(parent);} return parent; }} bool search(T ele,treenode<T>*root){ if(root==NULL) return false; else{while(root!=NULL){ if(ele==root->ele) return true; else if(ele<root->ele) return search(ele,root->left); else return search(ele,root->right);} return false;}} treenode<T>* search_node(T ele){return search_node(ele,root);} treenode<T>* search_node(T ele,treenode<T>*root){ int f=0;treenode<T>*p=root; if(root==NULL) return root; else{while(root!=NULL){ if(ele==root->ele) {f=1;return root;} else if(ele<root->ele) return search_node(ele,root->left); else return search_node(ele,root->right);} if(f==0)return NULL;}} treenode<T>* getparent(treenode<T>*current){ treenode<T>*pa=NULL; treenode<T>*p=current; if(p==root) return NULL; treenode<T>*pp=root; while(pp!=current){ if(current->ele<pp->ele){ pa=pp; pp=pp->left; } else if(current->ele>pp->ele){pa=pp;pp=pp->right;} else break;} return pa;} bool search(T ele){ return search(ele,root); }//搜索指定元素 void deleteele(treenode<T>*current){ treenode<T>*pa=getparent(current); treenode<T>*p=current; // 第一种情况:删除没有子节点的节点 if(root==NULL) throw runtime_error("empty"); if(p->left==NULL&&p->right==NULL){ if(p==root) root=NULL; else if(p==pa->left) pa->left=NULL; else pa->right=NULL;} //删除的节点只含右节点 if(p->left==NULL&&p->right!=NULL){ if(p==root) root=root->right; else if(p==pa->left) pa->left=p->right; else pa->right=p->right;} //如果要删除的节点只有左节点 if(p->left!=NULL&&p->right==NULL){ if(p==root) root=root->left; else if(p==pa->left) pa->left=p->left; else pa->right=p->left;} // 如果要删除的节点有两个子节点,即左右子节点都非空 // 方法是用要删除的节点的后续节点代替要删除的节点,并且删除后续节点(删除后续节点的时候同样的递归操作) // 其实,这里要用到的最多也就会发生两次,即后续节点不会再继续递归的删除下一个后续节点了 // 因为,要删除的节点的后续节点肯定是 要删除的那个节点的右子树的最小关键字,而这个最小关键字肯定不会有左节点 // 所以,在删除后续节点的时候肯定不会用到( 两个节点都非空的判断 ),如有有子节点,肯定就是有一个右节点。 if(p->left!=NULL&&p->right!=NULL){ treenode<T>*parent=p; treenode<T>*child=p->left; while(child->right!=NULL) { parent=child; child=child->right; } p->ele=child->ele; if(parent->left==child) parent->left=child->left; else parent->right=child->left; delete(child); } } void deleteele(T ele){ treenode<T>*p=search_node(ele); if(p==NULL) cout<<"no the value:"<<endl; else deleteele(p); } void prt(treenode<T>*left,treenode<T>*right){ if(left==NULL&&right==NULL)return ; else if(left==NULL&&right!=NULL) cout<<right->ele<<" "; else if(right==NULL&&left!=NULL) cout<<left->ele<<" "; else{ cout<<left->ele<<" "; cout<<right->ele<<" "; }} //深度优先遍历 void depthFirstSearch(treenode<T>*root){ stack<treenode<T> *> nodeStack; //使用C++的STL标准模板库 nodeStack.push(root); treenode<T> *node; while(!nodeStack.empty()){ node = nodeStack.top(); cout<<node->ele<<" "; //遍历根结点 nodeStack.pop(); if(node->right){ nodeStack.push(node->right); //先将右子树压栈 } if(node->left){ nodeStack.push(node->left); //再将左子树压栈 } } } void depthFirstSearch(){ depthFirstSearch(root);} void breadthFirstSearch(treenode<T>* root){ queue<treenode<T> *> nodeQueue; //使用C++的STL标准模板库 nodeQueue.push(root); treenode<T> *node; while(!nodeQueue.empty()){ node = nodeQueue.front(); nodeQueue.pop(); cout<<node->ele<<" "; if(node->left){ nodeQueue.push(node->left); //先将左子树入队 } if(node->right){ nodeQueue.push(node->right); //再将右子树入队 } } } void breadthfirst()//广度优先遍历 {breadthFirstSearch(root); } treenode<T>*getroot(){return root;} }; template<typename T> bitree<T>::bitree(T ele[],int size){ root=new treenode<T>(ele[0]); this->size=size;; for(int i=0;i<size;i++) insert(ele[i]);} template<typename T> bool bitree<T>::insert(T ele){ if(root==NULL) root=new treenode<T>(ele); else{ treenode<T>*parent=NULL; treenode<T>*p=root; while(p!=NULL){ if(ele<p->ele){parent=p; p=p->left;}//新元素小于父节点,则做父节点左孩纸 else if(ele>p->ele){parent=p;p=p->right;}//新元素大于父节点,则做父节点右边孩纸 else return false;} if(ele<parent->ele)parent->left=new treenode<T>(ele); else parent->right=new treenode<T>(ele); } size++; return true;} template<typename T> void bitree<T>::inorder(){ inorder(root);} template<typename T> void bitree<T>::inorder(treenode<T>*root){ if(root==NULL)return; /*inorder(root->left); cout<<root->ele<<" "; inorder(root->right);*/ stack<treenode<T>*> heapin; while(root!=NULL||!heapin.empty()){ if(root!=NULL){heapin.push(root); root=root->left;} else{ root=heapin.top(); heapin.pop(); cout<<root->ele<<" "; root=root->right;} } }//中序遍历,递归 template<typename T> void bitree<T>::preorder(){ preorder(root);} template<typename T> void bitree<T>::preorder(treenode<T>*root){ if(root==NULL)return; /*else{ cout<<root->ele<<" "; preorder(root->left); preorder(root->right);}*///注释处为递归算法 stack<treenode<T>* >ss; while(root!=NULL||!ss.empty()){ if(root!=NULL){ cout<<root->ele<<" "; ss.push(root); root=root->left;} else{ root=ss.top(); ss.pop(); root=root->right;}}}//前序遍历 template<typename T> void bitree<T>::postorder(){ postorder(root);} template<typename T> void bitree<T>::postorder(treenode<T>*root){ if(root==NULL) {return;} /*else{postorder(root->left); postorder(root->right); cout<<root->ele<<" "; }*/ treenode<T>*p=NULL; stack<treenode<T>*>s; treenode<T>*cu; s.push(root); while(!s.empty()){ cu=s.top(); if((cu->left==NULL&&cu->right==NULL)|| (p!=NULL&&(p==cu->left||p==cu->right))) { cout<<cu->ele<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); p=cu; } else { if(cu->right!=NULL) s.push(cu->right); if(cu->left!=NULL) s.push(cu->left); }} }//后序