二叉树大总结1 ---- 排序二叉树的各种题

来源:互联网 发布:淘宝店铺怎么看粉丝数 编辑:程序博客网 时间:2024/05/21 08:17
#include <iostream>#include <queue>#include <stack>using namespace std;/*  二叉查找树中的保存指针 */template<class T>class BinarySearchTree{public:        struct Node        {          T* value;          Node* left;          Node* right;          Node* parent;          Node(){left=0;right=0;parent=0;}               };        private:        static Node* root;public:       void add(T& t)       {          if(!root)          {              root = new Node;              root->value = &t;                  }else          {              Node* p = root;              Node* q = root;              bool isLeft = true;              while(p)              {                  q = p;                  if(*(p->value)>t)                  {                      isLeft = true;                      p = p->left;                                   }else                  {                      isLeft = false;                      p = p->right;                       }                      }                            Node * temp = new Node;              temp->value = const_cast<T*>(&t);              temp->parent = q;              if(isLeft)                 q->left = temp;              else                 q->right = temp;                }            }              void remove(const T& t)       {           if(!contain(t))             return;                        if(*(root->value)==t)           {               if(!root->left&&!root->right) //只有根                {                    delete root;                    root = 0;                     return;                                          }else if(!root->right)//没有右子树                {                    //找左子树的最大值                    Node *p = root->left;                    Node *q;                    while(p->right)                    {                         q = p;                         p = p->right;                                  }                    q->right = 0;                    root->value = p->value;                    delete p;                     return;                         }                               }           Node *p = root;           Node *q = root;           bool isLeft = true;           while(p)           {              if(*p->value==t)                 break;              else if(*p->value>t)              {                 isLeft = true;                 q = p;                 p = p->left;                   }else              {                 q = p;                 isLeft = false;                 p = p->right;                   }                   }           if(!(p->left)&&!p->right)           {              if(isLeft)                q->left = 0;              else                q->right = 0;              delete p;                                }else if(!p->right)           {               if(isLeft)               {                  q->left = p->left;                       }else               {                  q->right = p->left;                    }               p->left->parent = q;               delete p;                 }else  //右子树存在            {                Node* p1 =p;q = p1;p1 = p1->right;                while(p1->left)                {                    q = p1;p1 = p1->left;                               }//可能右孩子没有左子树if(q->right==p1)q->right = p1->right;else                    q->left = p1->right;                if(p1->right)                   p1->right->parent = q;                p->value = p1->value;                delete p1;           }              }                     bool contain(const T& t)       {            Node *p = root;            while(p)            {               if(*(p->value)==t)                  return true;               else if(*(p->value)<t)                  p = p->right;               else                  p = p->left;                    }            return false;          }                     T findMin()       {           if(!root)               throw "null";  //寻找最小数但里面什么都没有STL是怎么做的?            Node* p = root;           while(p->left)           {              p = p->left;                   }           return *(p->value);                 }              T findMax()       {           if(!root)              throw "null";           Node* p = root;           while(p->right)              p = p->right;           return *(p->value);                  }              bool isEmpty(){return root==0?true:false;}              BinarySearchTree(){root=0;}              virtual ~BinarySearchTree()       {           deleteTree(root);               }              //递归遍历        void postTraversal(Node* node=root)       {            if(node)            {                 postTraversal(node->left);                postTraversal(node->right);                cout<< *(node->value)<<" ";                      }       }              void preTraversal(Node* node=root)       {            if(node)            {                cout<< *(node->value)<<" ";                   preTraversal(node->left);                preTraversal(node->right);                    }            }              void inorderTraversal(Node* node=root)       {            if(node)            {               inorderTraversal(node->left);               cout<< *(node->value)<<" ";               inorderTraversal(node->right);                    }            }              //非递归遍历        void postTraversalUsingStack()       {            stack<Node*> s;            Node* p = root;            bool hasVisited = false;            do            {                while(p)                {                    s.push(p);                    p = p->left;                        }                if(!s.empty())                {                    p = s.top();                    s.pop();                            }else                           break;                bool copy = hasVisited;                if(!s.empty()&&s.top()->right==p)                      hasVisited = true;                else                   hasVisited = false;                if(p->right&&!copy)                {                   s.push(p);                   p = p->right;                        }                    else                {                   cout<<*p->value<<" ";                   p = 0;                    }                                                             }            while(true);          }              void preTraversalUsingStack()       {            stack<Node*> s;            Node* p = root;            do            {                while(p)                {                    cout<< *p->value<<" ";                    s.push(p);                     p = p->left;                       }                if(!s.empty())                {                   p = s.top();                   s.pop();                           }else                   break;                if(p->right)                   p = p->right;                else                   p = 0;                                        }            while(true);       }              void inorderTraversalUsingStack()       {            stack<Node*> s;            Node* p = root;                        do            {               while(p)               {                   s.push(p);                   p = p->left;                      }               if(!s.empty())               {                   p = s.top();                   s.pop();                         }else                   break;                              cout<<*p->value<<" ";               if(p->right)                  p = p->right;               else                  p = 0;                                 }            while(true);            }                     /*          STL中的queue:                 push(x) 将x压入队列的末端                pop() 弹出队列的第一个元素(队顶元素),注意此函数并不返回任何值                front() 返回第一个元素(队顶元素)                back() 返回最后被压入的元素(队尾元素)                empty() 当队列为空时,返回true                size() 返回队列的长度       */       //层序遍历        void traversalByLayer()       {           queue<Node*> q;           q.push(root);           while(!q.empty())           {               Node* temp = q.front();               q.pop();               if(temp->left)                  q.push(temp->left);               if(temp->right)                  q.push(temp->right);               cout<< *(temp->value)<<" ";                           }            }       //递归翻转镜像        void mirror(Node* node=root)       {            if(node)            {                mirror(node->left);                mirror(node->right);                Node* temp=node->left;node->left=node->right;node->right=temp;                   }         }               //非递归翻转镜像       void mirrorIteratively()       {            stack<Node*> s;            Node* p = root;                        do            {                while(p)                {                    Node* temp=p->left;p->left=p->right;p->right=temp;                    s.push(p);                    p = p->left;                        }                if(!s.empty())                {                   p = s.top();                   s.pop();                              }else                   break;                 if(p->right)                   p = p->right;                else                   p = 0;                                 }            while(true);           }              //寻找叶子数        int getLeafNumber(Node* node=root)       {           if(!node)              return 0;           if(!node->left&&!node->right)              return 1;           int left = getLeafNumber(node->left);           int right = getLeafNumber(node->right);           return left+right;         }              //寻找树的高度        int getHeight(Node* node=root)       {           if(!node)              return 0;           if(!node->left&&!node->right)              return 1;           int left = getHeight(node->left);           int right = getHeight(node->right);           int result =  left>right?left:right;           return result+1;              }              //寻找最大距离       int findMaxDistance(Node* node=root)       {           if(!node)              return 0;           int n1 = getHeight(node->left);           int n2 = getHeight(node->right);           return n1+n2+1;           }               //寻找共同最低父节点:等价于Y型链表求交点        T parent(const T& t1,const T& t2)       {            Node* node1 = getNode(t1);            Node* node2 = getNode(t2);            if(!node1||!node2)               throw "null";            int num1 = 0;            int num2 = 0;            Node* p;            p = node1;            while(p->parent)            {               num1++;               p = p->parent;                            }            p = node2;            while(p->parent)            {               num2++;               p = p->parent;                            }            if(num1<num2)            {                int n=num1;num1=num2;num2=n;                Node* temp=node1;node1=node2;node2=temp;                        }            int n = num1-num2;            while(n--)            {               node1 = node1->parent;                      }                        while(true)            {               if(node1==node2)               {                  cout<<*node1->value<<endl;                  return   *node1->value;                             }               node1 = node1->parent;               node2 = node2->parent;                                        }                                          }              //将二叉树变成排序的双向链表        Node* convert(Node* node=root,Node* last=0)       {            if(!node)               return 0;            if(node->left)               last = convert(node->left,last);                         node->left = last;            if(last)               last->right = node;                           last = node;                        if(node->right)               last = convert(node->right,last);                        return last;          }private:              void deleteTree(Node* node)       {            if(node)            {                deleteTree(node->left);                deleteTree(node->right);                delete node;                    }           }              Node* getNode(const T& t)       {           Node *p = root;            while(p)            {               if(*(p->value)==t)                  return p;               else if(*(p->value)<t)                  p = p->right;               else                  p = p->left;                    }            return 0;            }   };template<class T>BinarySearchTree<T>::Node* BinarySearchTree<T>::root = 0;void main(){    BinarySearchTree<int> bst;    int a[] = {4,8,10,5,9,2,3,6,15,12,17};    for(int i=0;i<sizeof(a)/sizeof(int);i++)        bst.add(a[i]);          bst.inorderTraversal();cout<<endl;/*bst.inorderTraversalUsingStack();cout<<endl;    bst.preTraversal();cout<<endl;bst.preTraversalUsingStack();cout<<endl;bst.postTraversal();cout<<endl;bst.postTraversalUsingStack();cout<<endl;*//*bst.remove(9);bst.inorderTraversal();cout<<endl;bst.remove(2);bst.inorderTraversal();cout<<endl;bst.remove(4);bst.inorderTraversal();cout<<endl;*//*cout<<bst.findMin()<<endl;cout<<bst.findMax()<<endl;bst.traversalByLayer();cout<<endl;*//*bst.mirror();bst.mirrorIteratively();bst.inorderTraversal();cout<<endl;*/cout<<bst.getLeafNumber()<<" "<<bst.getHeight()<<" "<<bst.findMaxDistance()<<" "<<bst.parent(15,6);cout<<endl;BinarySearchTree<int>::Node* p = bst.convert();while(p){   cout<<*p->value<<" ";   p = p->left;}}