面试题二叉树相关问题总结

来源:互联网 发布:征服者rd88升级软件 编辑:程序博客网 时间:2024/05/16 15:50

二叉树中的面试题比较常见的题型大概有下面几个:创建一颗二叉树(先序,中序,后序)、遍历一颗二叉树(先序,中序,后序和层次遍历)、求二叉树中叶子节点的个数、求二叉树的高度、求二叉树中两个节点的最近公共祖先打印和为某一值的全部路径、求某一节点是否在一个树中等等。

再详细的说这些面试题之前,不妨先看一下几种常见的二叉树:

完全二叉树:若二叉树的高度是h,除第h层之外,其他(1~h-1)层的节点数都达到了最大个数,并且第h层的节点都连续的集中在最左边。实际上,完全二叉树和堆联系比较紧密~~~

满二叉树:除最后一层外,每一层上的所有节点都有两个子节点,最后一层都是叶子节点。

哈夫曼树:这是一种带权路径长度最短的树。哈夫曼编码就是哈夫曼树的应用。

平衡二叉树:所谓平衡二叉树指的是,所有的左右两个子树的高度差的绝对值不超过 1。

红黑树:红黑树是每个节点都带颜色的树,节点颜色或是红色或是黑色,红黑树是一种查找树。红黑树有一个重要的性质,从根节点到叶子节点的最长的路径不多于最短的路径的长度的两倍。对于红黑树,插入,删除,查找的复杂度都是O(log N)。


首先给定统一二叉树的数据结构定义:

struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}};

题目1:操作给定的二叉树,将其变换为源二叉树的镜像。

    void Mirror(TreeNode *pRoot)     {        if(!pRoot)            return;        TreeNode *temp=pRoot->left;        pRoot->left=pRoot->right;        pRoot->right=temp;        Mirror(pRoot->left);        Mirror(pRoot->right);    }


题目2:从上往下打印出二叉树的每个节点,同层节点从左至右打印。(层序遍历)

思路:借助队列实现。每次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到一个队列的结尾。接下来到队列的头部取出最早进入队列的点,重复前面的打印操作,直到队列中所有的结点都被打印出来。

    vector<int> PrintFromTopToBottom(TreeNode *root)     {        vector<int> r;        if(!root)            return r;         deque <TreeNode *> q;        q.push_back(root);        while(!q.empty())        {           TreeNode *temp=q.front();           q.pop_front();           r.push_back(temp->val);           if(temp->left)               q.push_back(temp->left);           if(temp->right)               q.push_back(temp->right);        }        return r;    }

题目3:二叉树的深度:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

int TreeDepth(TreeNode* pRoot)    {        if(pRoot==NULL)               return 0;        int Left=TreeDepth(pRoot->left);        int Right=TreeDepth(pRoot->right);        return Left>Right?Left+1:Right+1;             }

题目4:输入一棵二叉树,判断该二叉树是否是平衡二叉树。

 int GetDepth(TreeNode* pRoot)    {        if(pRoot==NULL)            return 0;        else            return 1+max(GetDepth(pRoot->left),GetDepth(pRoot->right));    }    bool IsBalanced_Solution(TreeNode* pRoot)    {        if(pRoot==NULL)            return true;        int Left=GetDepth(pRoot->left);        int Right=GetDepth(pRoot->right);        int diff=Left-Right;        if(diff<-1||diff>1)            return false;        else            return IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right);    }


题目5:对称的二叉树,请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

 bool isSymmetrical(TreeNode* pRoot)    {      if(pRoot==NULL)         return true;      else         return isSymmetrical1(pRoot->left,pRoot->right);    } bool isSymmetrical1(TreeNode *pRoot1,TreeNode* pRoot2) {      if(pRoot1==NULL&&pRoot2==NULL)          return true;      if(pRoot1==NULL||pRoot2==NULL)          return false;      if(pRoot1->val==pRoot2->val)         return isSymmetrical1(pRoot1->left,pRoot2->right)&&isSymmetrical1(pRoot1->right,pRoot2->left);      return false; }

题目6:按照之字形打印二叉树,请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

vector<vector<int> > Print(TreeNode* pRoot)    {        vector<vector<int>>result;        if(pRoot==NULL)            return result;        stack <TreeNode*> stack1,stack2;             //stack1存储奇数层 stack2存储偶数层        stack1.push(pRoot);        while(!stack1.empty()||!stack2.empty())        {            vector<int> level;            if(!stack1.empty())            {              while(!stack1.empty())              {                 TreeNode *temp=stack1.top();                 level.push_back(temp->val);                 if(temp->left)                    stack2.push(temp->left);                 if(temp->right)                    stack2.push(temp->right);                 stack1.pop();              }            }            else            {                while(!stack2.empty())                {                    TreeNode*temp=stack2.top();                    level.push_back(temp->val);                    if(temp->right)                       stack1.push(temp->right);                    if(temp->left)                       stack1.push(temp->left);                    stack2.pop();                }            }            result.push_back(level);        }        return result;    }

目7:把二叉树打印成多行,从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

      vector<vector<int> > Print(TreeNode* pRoot)        {            vector<vector<int> > result;            if(!pRoot)                return result;            queue<TreeNode*>nodes;            vector<int>line;            nodes.push(pRoot);            int currLevel=1;            //记录nodes中存的当前层的结点个数            int nextLevel=0;            //记录nodes中存的下一层的结点个数            while(!nodes.empty())            {               TreeNode *temp=nodes.front();               if(temp->left)               {                   nodes.push(temp->left);                   nextLevel++;               }               if(temp->right)               {                   nodes.push(temp->right);                   nextLevel++;               }               line.push_back(temp->val);               currLevel--;               nodes.pop();               if(0==currLevel)                     //当当前层已经处理完了,把当前line输出到结果result中,完成一行                {                   result.push_back(line);                   line.clear();                   currLevel=nextLevel;                   nextLevel=0;               }            }            if(!line.empty())               result.push_back(line);            return result;        }

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

   TreeNode* KthNode(TreeNode* pRoot, unsigned int k)    {        if(!pRoot||k<=0)            return NULL;        //中序遍历就是二叉搜索树的排序        vector<TreeNode *> array;        InOrder(pRoot,array);        if(k>array.size())            return NULL;        return array[k-1];    }     void InOrder(TreeNode *pRoot,vector<TreeNode *>&Order)     {        if(!pRoot)            return;        InOrder(pRoot->left,Order);        Order.push_back(pRoot);        InOrder(pRoot->right,Order);     }

目9:二叉搜索树的后序遍历序列,输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

bool VerifySeqenceOfBST(int *seqence,int length){if(seqence==NULL||length<=0)return false;int root=seqence[length-1];//在二叉搜素树中左子树的结点小于根结点int i=0;for(;i<length-1;i++){if(seqence[i]>root)break;}//在二叉搜素树中右子树的结点大于根结点for(int j=i;j<length-1;j++){if(seqence[j]<root)return false;}//判断左子树是不是二叉搜索树bool left=true;if(i>0)left=VerifySeqenceOfBST(seqence,i);//判断右子树是不是二叉搜索树bool right=true;if(i<length-1)right=VerifySeqenceOfBST(seqence+i,length-i-1);return left&&right;}

目10:树的子结构,输入两颗二叉树A,B,判断B是不是A的子结构。

bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)    {       bool r=false;       if(pRoot1!=NULL&&pRoot2!=NULL)       {          if(pRoot1->val==pRoot2->val)              r=DoesTree1HaveTree2(pRoot1,pRoot2);          if(!r)              r=HasSubtree(pRoot1->left,pRoot2);          if(!r)              r=HasSubtree(pRoot1->right,pRoot2);       }        return r;    }    bool DoesTree1HaveTree2(TreeNode *pRoot1,TreeNode *pRoot2)    {        if(pRoot2==NULL)            return true;        if(pRoot1==NULL)            return false;        if(pRoot1->val!=pRoot2->val)            return false;                return DoesTree1HaveTree2(pRoot1->left,pRoot2->left)&&DoesTree1HaveTree2(pRoot1->right,pRoot2->right);    }




0 0
原创粉丝点击