二叉查找树的典型面试题目汇总

来源:互联网 发布:sql查询去重 编辑:程序博客网 时间:2024/05/22 15:54
#include <iostream>#include <vector>#include <stack>#include <queue>using namespace std;typedef struct BSTreeNode{int num;BSTreeNode* leftChild;BSTreeNode* rightChild;}*TreeNode;TreeNode search(TreeNode root,int key){if (!root){return NULL;}if (key==root->num){return root;}if (key<root->num){search(root->leftChild,key);}return search(root->rightChild,key);}//利用指针的指针进行改变树结构。void insert_node(TreeNode* node,int num){if ((*node)==NULL){(*node)=new BSTreeNode;(*node)->num=num;(*node)->leftChild=(*node)->rightChild=NULL;}else{if (num<(*node)->num){insert_node(&(*node)->leftChild,num);}else if (num>(*node)->num){insert_node(&(*node)->rightChild,num);}elsecout<<" insert duplicated elements \n";}}//利用引用去改变整个树结构。void insert_node2(TreeNode &root,int num){if (root==NULL){root=new BSTreeNode;root->num=num;root->leftChild=root->rightChild=NULL;}else{if (num<root->num){insert_node2(root->leftChild,num);}else if (num>root->num){insert_node2(root->rightChild,num);}elsecout<<" insert duplicated elements \n";}}//中序遍历输出树结果。void inorder(TreeNode root){if (root!=NULL){inorder(root->leftChild);cout<<root->num<<" ";inorder(root->rightChild);}}//非递归的中序遍历。void inorderTraverse(TreeNode root){stack<TreeNode>sta;TreeNode p=root;while (p||sta.size()){if (p){sta.push(p);p=p->leftChild;}else{p=sta.top();cout<<p->num<<" ";sta.pop();p=p->rightChild;}}}/*题目:输入一个整数和棵二元树。从树的根结点开始往下访问一直到叶所经过有形成条路径。打印出和与输入整数相等的所有路径。*/void findPath(TreeNode root,vector<int>&path,int current_sum,int expected_sum){//这个路径必须包括根节点,而且必须是连接的的线路。if (root==NULL||current_sum>expected_sum)//剪枝条件{return;}current_sum+=root->num;//path 存下数字路径path.push_back(root->num);bool is_leaf=(!root->leftChild)&&(!root->rightChild);if (is_leaf&&(expected_sum==current_sum)){//符合条件输出该情况树节点。vector<int>::iterator it;for (it=path.begin();it!=path.end();it++){cout<<*it<<" ";}cout<<endl;}//类似于全排列算法的实现。先加入某个节点递归,然后在删除递归。if (root->leftChild){findPath(root->leftChild,path,current_sum,expected_sum);}if (root->rightChild){findPath(root->rightChild,path,current_sum,expected_sum);}current_sum-=root->num;path.pop_back();}//输入一颗二元查找树,将该转换为它的镜像即在转换后的二元查找树中,左子结点都大于右。递归方法简单实现TreeNode traverseTree(TreeNode& root){if (root){//递归逻辑一定清楚!!TreeNode left=root->leftChild;TreeNode right=root->rightChild;root->leftChild=traverseTree(right);root->rightChild=traverseTree(left);}return root;}/*使用循环方式实现镜像的转换。解法一:用递归。假设当前结点为root,只需交换该结点的左右子女,然后分别递归求解左子树和右子树即可。解法二:用循环,需要一个辅助栈完成,每次取栈顶元素交换左右子女,然后将左右子女分别压入辅助栈,当栈中元素为空时,结束循环。其实不论是递归也好,循环也好,都是利用栈的特性完成。*/TreeNode traverseTreeType2(TreeNode &root){if (root){stack<TreeNode>sta;sta.push(root);while (sta.size()){TreeNode pNode=sta.top();TreeNode leftChild=pNode->leftChild;TreeNode rightChild=pNode->rightChild;sta.pop();if (leftChild){sta.push(leftChild);}if (rightChild){sta.push(rightChild);}pNode->leftChild=rightChild;pNode->rightChild=leftChild;}}return root;}//求树的深度递归实现。int deepth(TreeNode root){int leftDeep=0,RightDeep=0;if (root==NULL){return 0;}RightDeep= deepth(root->rightChild)+1;leftDeep=deepth(root->leftChild)+1;return leftDeep>RightDeep? leftDeep:RightDeep;}/*层次遍历树过程创建一个队列q;将根放入队列;while(队列非空){从队列取出一个元素并访问;如果该元素有左子树就将它放入队列;如果该元素有右子树就将它放入队列;}*/void levelTravese(TreeNode root){queue<TreeNode>que;que.push(root);while (que.size()){TreeNode pNode=que.front();que.pop();cout<<pNode->num<<" ";if (pNode->leftChild){que.push(pNode->leftChild);}if (pNode->rightChild){que.push(pNode->rightChild);}}}int main(){int a[]={10,5,12,4,7,6,11};TreeNode root=NULL;for (int i=0;i<7;i++){//insert_node(&root,a[i]);insert_node2(root,a[i]);}cout<<"insert ending 中序遍历输出"<<endl;//inorder(root);inorderTraverse(root);cout<<endl;levelTravese(root);cout<<endl;vector<int>path;int current_sum=0;int expected_sum=28;findPath(root,path,current_sum,expected_sum);//traverseTree(root);traverseTreeType2(root);inorder(root);return 0;}

0 0