二叉树总结

1.二叉树创建

class Solution
{
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin)
    {
        if(pre.size()<=0||vin.size()<=0)
            return NULL;
        TreeNode *root=new TreeNode(pre[0]);
        //前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
        for(int i=0;i<vin.size();i++)
        {
            if(pre[0]==vin[i])
            {

                root->left=reConstructBinaryTree(copy(pre,1,i),copy(vin,0,i-1));
                root->right=reConstructBinaryTree(copy(pre,i+1,pre.size()-1),copy(vin,i+1,vin.size()-1));                            
                break;
            }

        }
        return root;
    }
    vector<int> copy(vector<int> array,int begin,int end)
    {
        vector<int> temp;
        while(begin<=end)
        {
            temp.push_back(array[begin++]);
        }
        return temp;
    }
};
    int input;  
    scanf("%d",&input);         //按先序建立二叉树  
    if(input == 0)  
    {  
        root = NULL;   //置为NULL后结束  
        return root;     
    }  
    root = (TreeNode *)malloc(sizeof(TreeNode));  
    root ->val = input;  
    root->left = CreateTree(root->left);  
    root->right = CreateTree(root->right);  
    return root;  
}  
2.二叉树递归遍历

 void preorder(Node* root)//先序遍历打印树的各个节点  
    {  
        if (root)  
        {  
            cout<<root->val<<" ";  //访问当前节点的值
            preorder(root->left); //递归遍历左子树 
            preorder(root->right); //递归遍历右子树 
        }  
    }  
    void inorder(Node* root)//中序遍历打印树的各个节点  
    {  
        if (root)  
        {  
            preorder(root->left);  //递归遍历左子树 
            cout<<root->val<<" ";  //访问当前节点的值
            preorder(root->child);  //递归遍历右子树 
        }  
    }  
    void postorder(Node* root)//后序遍历打印树的各个节点  
    {  
        if (root)  
        {  
            preorder(root->left);  //递归遍历左子树 
            preorder(root->right);  //递归遍历右子树 
            cout<<root->val<<" ";  //访问当前节点的值
        }  
    }  
3.二叉树非递归遍历


//中序遍历  
void InOrderWithoutRecursion1(TreeNode* root)  
{  
    //空树  
    if (root == NULL)  
        return;  
    //树非空  
    TreeNode* p = root;  
    stack<TreeNode*> s;  
    while (!s.empty() || p)  
    {  
        //一直遍历到左子树最下边,边遍历边保存根节点到栈中  
        while (p)  
        {  
            s.push(p);  
            p = p->left;  
        }  
        //当p为空时,说明已经到达左子树最下边,这时需要出栈了  
        if (!s.empty())  
        {  
            p = s.top();  
            s.pop();  
            cout << setw(4) << p->val;  
            //进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)  
            p = p->right;  
        }  
    }  
}  
三、 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
     vector<vector<int> > res;
        vector<vector<int> > Print(TreeNode* pRoot) 
        {
            if(!pRoot)
                return res;
        
    	 queue <TreeNode*> q;
    	 q.push(pRoot);
            
   		 vector<int> temp; 
    	 while (!q.empty()) 
         {
            int size=q.size();
           
            for (int i=0;i<size;i++) {      //一次处理一层的数据
                TreeNode *node=q.front();
                temp.push_back(node->val);
                q.pop();
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            res.push_back(temp);
            temp.clear();
        }
            return res;
   }
};
之字形打印二叉树

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
     vector<vector<int> > res;
        vector<vector<int> > Print(TreeNode* pRoot) 
        {
            if(!pRoot)
                return res;

         queue <TreeNode*> q;
         q.push(pRoot);
		bool flag = 1;
         vector<int> temp;
         while (!q.empty()) 
         {
            int size=q.size();
            for (int i=0;i<size;i++) 
            {      //一次处理一层的数据
                TreeNode *node=q.front();
                temp.push_back(node->val);
                q.pop();
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
                    
            }
              if(flag)
              {
                  res.push_back(temp);
              }
             else
             {
                 reverse(temp.begin(),temp.end());
                 res.push_back(temp);
             }
            flag =!flag; 
            temp.clear();
        }
            return res;
   }
};
二叉树深度

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
   int TreeDepth(TreeNode* pRoot)
   {
        if(pRoot == NULL)
            return 0;
        queue<TreeNode*> queTree;
        queTree.push(pRoot);
        int depth = 0;
        while(!queTree.empty())
        {
            int size = queTree.size();
            depth++;
            while(size != 0)
            {
                TreeNode* temp = queTree.front();
                queTree.pop();
                if(temp->left)
                    queTree.push(temp->left);
                if(temp->right)
                    queTree.push(temp->right);
                size--;
            }
        }
        return depth;
    }
};
class Solution {
public:
    int TreeDepth(TreeNode* pRoot){
        if(!pRoot) return 0 ;
        return max(1+TreeDepth(pRoot->left), 1+TreeDepth(pRoot->right));
    }
};


否是平衡二叉树。

class Solution {
public:
     int tree_deep(TreeNode* pRoot)
     {
         if(pRoot == NULL)
         {
             return 0;
         }
         int left = tree_deep(pRoot->left);
          int right = tree_deep(pRoot->right);
         return left > right?(left+1):(right+1);
     }
         
    
    bool IsBalanced_Solution(TreeNode* pRoot) {
	     if(pRoot == NULL)
         {
             return true;
         }
         int leftr = tree_deep(pRoot->left);
          int rightr = tree_deep(pRoot->right);
        int diff =abs(leftr - rightr);
        if(diff > 1)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
};
输入两棵二叉树A,B,判断B是不是A的子结构

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if (!pRoot2) return false;
        if (!pRoot1) return false;
        return (check(pRoot1,pRoot2) || HasSubtree(pRoot1->left,pRoot2) || HasSubtree(pRoot1->right,pRoot2));
    }
private:
    bool check(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if (!pRoot2) return true;
        if (!pRoot1) return false;
        if (pRoot1->val == pRoot2->val) return (check(pRoot1->left,pRoot2->left)&&check(pRoot1->right,pRoot2->right));
        return false;
    }
};

变换为源二叉树的镜像。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot == NULL)
        {
            return;
        }
        TreeNode *tem = NULL;
        tem = pRoot->left;
        pRoot->left = pRoot->right;
        pRoot->right = tem;
        Mirror(pRoot->left);
        Mirror(pRoot->right);

    }
};

二叉树中和为某一值的路径
class Solution {
private:
    vector<vector<int> > result;
    void findnode(TreeNode *root, const int expectNumber,int sum,vector<int> &path)
    {
        if (root == NULL)
            
        {
            return;
        }
            
            path.push_back(root->val);
            sum += root->val;

            if (!root->left && !root->right && sum == expectNumber)
            {
                result.push_back(path);
            }
            else {
                findnode(root->left,expectNumber,sum,path);
                findnode(root->right,expectNumber,sum,path);
            }
            path.pop_back();
            sum -= root->val;
    }
public:
    vector<vector<int> > FindPath(TreeNode* root, int expectNumber)
    {
        vector<int> path;
        findnode(root,expectNumber,0,path);
        return result;
    }
};
判断该数组是不是某二叉搜索树的后序遍历的结果

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int sizeq = sequence.size();
		if(sizeq == 0)
        {
            return false;
        }
        else if(sizeq == 1)
        {
            return true;
        }
        return search_seq(sequence,0,sizeq-1);
    }
    bool search_seq(vector<int> s,int start,int end)
    {
        if(start > end)
        {
            return true;
        }
        int i = start;
        while(s[i] < s[end])
        {
            ++i;
        }
        for(int j=i;j<end;j++)
        {
            if(s[j] < s[end])
            {
                return false;
            }
        
    	}
        return search_seq(s,0,i-1) && search_seq(s,i+1,end-1);
}
};
二叉搜索树转换成一个排序的双向链表

/*
非递归中序遍历,加个指针pre记录上一次出栈值
*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode *head = NULL, *pre = NULL;//head 输出,pre记录上一次出栈值
        stack<TreeNode*> s;
        while (pRootOfTree || !s.empty())
        {
            while (pRootOfTree)
            {
                s.push(pRootOfTree);
                pRootOfTree = pRootOfTree->left;
            }
            if (!s.empty())
            {
                pRootOfTree = s.top();
                s.pop();
                if (pre != NULL)
                {
                    pre->right = pRootOfTree;
                    pRootOfTree->left = pre;
                }
                else//pre为空,表示s第一次出栈,第一次出栈值为最左值,即输出值
                    {
                    head = pRootOfTree;
                }
                pre = pRootOfTree;
                pRootOfTree = pRootOfTree->right;
            }
        }
        return head;
    }
};

中序遍历顺序的下一个结点并且返回

class Solution {
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        if(pNode==nullptr) return nullptr; //情况1.空树,返回空
        if(pNode->right!=nullptr)         //情况2.有右子树,则本节点的下一个节点即是其右子树的最左的子节点
        {
            TreeLinkNode*p=pNode->right;
            while(p->left!=nullptr) {p=p->left;}
            return p;
        }
        while(pNode->next!=nullptr) //情况3.1没有右子树,则本节点的下一个节点即是 满足:本节点的父节点(1)是他父节点(2)的左子节点 这一条件时,返回(2)
        {
           if(pNode->next->left==pNode) return pNode->next;
            pNode=pNode->next;
        }
        return nullptr; //情况3.2 已经找到根节点了,结束上面的循环,那么本节点的下一个节点就指向nullptr
    }
};

给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
   int count = 0;
    TreeNode *res = NULL;
         void inOrder(TreeNode * root,int k)  
        {  
            if (root == NULL)  
            {  
                return;  
            }  
            inOrder(root->left,k);  
            count++;
             if(count == k)
             {
                 res = root;
             }
            inOrder(root->right,k);  
        }  
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        if(!pRoot)
            return pRoot;
        inOrder(pRoot,k);
      
        return res;
    }
};

求二叉树中节点的个数  

size_t size(Node* root)//求树中的节点个数
    {
        size_t count = 0;
        if (NULL == root)
        {
            count = 0;
        }
        else
        {
            //当前节点 = 左子树节点 + 右子树节点 + 1
            count = size(root->left) + size(root->right)+ 1;
        }
        return count;
    }
求二叉树中叶子节点的个数  
size_t getleafsize(Node* root)//求叶节点的个数
    {
        if (NULL == root)//空树
        {
            return 0;
        }
        if (NULL == root->left && NULL == root->right)//左叶节点右节点均为空,即
        {
            return 1;
        }
        else//左子树的叶节点+右子树的叶节点
        {
            return getleafsize(root->left)+getleafsize(root->right);
        }
    }
求二叉树第K层的节点个数(假设根节点为第1层)  

size_t getklevelsize(Node* root,size_t k)//树中第k层的节点个数
    {
        assert(k>0);

        size_t count = 0;
        if (NULL == root)
        {
            return 0;
        }
        if (k == 1)
        {
            count++;
        }
        else
        {
            count =  getklevelsize(root->left,k-1)
                + getklevelsize(root->right,k-1);
        }
        return count;
    }
判断一个节点是否在二叉树中  

bool _Find(Node* root,const T& data)    //查找指定数据的节点
    {
        if (NULL == root)
        {
            return false;
        }
        else if (root->val== data)
        {
            return true;
        }
        else
        {
            bool isIn = false;
            if (root->left && !isIn)
                isIn = _Find(root->left,data);
            if (root->right && !isIn)
                isIn = _Find(root->right,data);
            return isIn;
        }
    }

求二叉树中最远的两个节点的距离  

int _RemoteDistance1(Node* root,int& distance)
    {
        if (NULL == root)
        {
            return 0;
        }
        int tmp = _Depth(root->_left)+_Depth(root->_right);//递归去求每棵子树的最远距离

        if (distance < tmp)//用全局变量保存每棵子树的最远距离,并不断更新
        {
            distance = tmp;
        }
        return distance;
    }
求二叉查找树的公共祖先


/*1 如果两个节点都比当前节点小, 那公共祖先必然是当前节点的左子树上, 所以递归左子树;

2 如果两个节点都比当前节点大, 那么同上, 递归右子树;

3 如果两个节点有一个为当前节点, 则当前节点为公共节点; 如果两个节点分别比当前节点小和大, 那么当前节点必为公共节点.*/

class Solution {  
public:  
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {  
        if(root == NULL || p == NULL || q == NULL)  
            return root;  
        if(p->val > root->val && q->val > root->val)  
            return lowestCommonAncestor(root->right, p, q);  
        else if(p->val < root->val && q->val < root->val)  
            return lowestCommonAncestor(root->left, p, q);  
        else  
            return root;  
    }  
}; 

求二叉树的公共祖先

 /*直到递归到某节点满足一定的条件, 返回该节点; 否则继续递归, 若到叶子节点, 返回空. 那么最终返回的必然为两个被求节点的公共祖先. 
具体思路:
1 如果当前节点为空, 返回空;
2 如果当前节点为两个节点中的一个, 或者当前节点恰好是两个节点的父亲节点, 那么返回该节点;
3 递归遍历当前节点左子树;
4 递归遍历当前节点右子树;
5 如果3 和 4 返回的都不是空, 那么当前节点必为公共祖先, 返回当前节点;
6 如果5不满足, 但3返回的不为空, 则返回3返回的节点指针;
7 如果5不满足, 但4返回的不为空, 则返回4返回的节点指针*/
class Solution {  
public:  
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {  
        if(root == NULL)  
            return NULL;  
        if(root == p || root == q || (root->left == p && root->right == q) || (root->left == q && root->right == p))  
            return root;  
        TreeNode* leftReturn = lowestCommonAncestor(root->left, p, q);  
        TreeNode* rightReturn = lowestCommonAncestor(root->right, p, q);  
        if(leftReturn != NULL && rightReturn != NULL)  
            return root;  
        if(leftReturn != NULL)  
            return leftReturn;  
        if(rightReturn != NULL)  
            return rightReturn;  
    }  
};






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值