二叉樹相關筆試面試題(一)
阿新 • • 發佈:2019-01-03
本部落格內容
一、二叉樹的結構
二、求二叉樹中節點個數
三、求二叉樹的第k層的節點個數
四、求二叉樹的葉子節點的個數
五、求二叉樹的深度
六、二叉樹的遍歷(前序、中序、後序)
七、層序遍歷二叉樹(從上到下、從左到右)
八、將二叉搜尋樹變為有序的雙向連結串列(要求:不建立新節點,只調整指標)
九、判斷二叉樹是否相同
十、判斷二叉樹是否是平衡二叉樹
一、二叉樹的結構
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode * m_pLeft;
BinaryTreeNode * m_pRight;
};
二、求二叉樹中節點個數
//遞迴求解
unsigned int GetNodeNum(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return 0;
return GetNodeNum(pRoot->m_pLeft)+GetNodeNum(pRoot->m_pRight)+1;
}
三、求二叉樹的第k層的節點個數
//遞迴求解
int GetNumKthLevel(BinaryTreeNode *pRoot,int k)
{
if(pRoot==NULL||k<1)
return 0;
if(k==1)
return 1;
int numLeft=GetNumKthLevel(pRoot->m_pLeft,k-1);
int numRight=GetNumKthLevel(pRoot->m_pRight,k-1);
return (numLeft+numRight);
}
四、求二叉樹的葉子節點的個數
int GetLeafNodeNum(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return 0;
if(pRoot->m_pLeft== NULL && pRoot->m_pRight==NULL)
return 1;
int numLeft=GetLeafNodeNum(pRoot->m_pLeft);
int numRight=GetLeafNodeNum(pRoot->m_pRight);
return numLeft+numRight;
}
五、求二叉樹的深度
unsigned int GetDepth(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return 0;
int left=0,right=0;
left=GetDepth(pRoot->m_pLeft);
right=GetDepth(pRoot->m_pRight);
return left>right?left+1:right+1;
}
六、二叉樹的遍歷(前序、中序、後序)
void visit(BinaryTreeNode * pRoot)
{
printf("%d",pRoot->m_nValue);
}
//前序
void PreOrderTraverse(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return ;
visit(pRoot);
PreOrderTraverse(pRoot->m_pLeft);
PreOrderTraverse(pRoot->m_pRight);
}
//中序
void InOrderTraverse(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return ;
InOrderTraverse(pRoot->m_pLeft);
visit(pRoot);
InOrderTraverse(pRoot->m_pRight);
}
//後序
void PostOrderTraverse(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return ;
PostOrderTraverse(pRoot->m_pLeft);
PostOrderTraverse(pRoot->m_pRight);
visit(pRoot);
}
七、層序遍歷二叉樹(從上到下、從左到右)
①利用佇列實現
void LevelTraverse(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return ;
queue<BinaryTreeNode * > que;
que.push(pRoot);
while(!que.empty())
{
BinaryTreeNode * temp=que.front();
visit(temp);
que.pop();
if(temp->m_pLeft)
que.push(temp->m_pLeft);
if(temp->m_pRight)
que.push(temp->m_pRight);
}
return ;
}
②按層列印二叉樹(將每一層儲存到vector中)
vector<vector<int> > Print(BinaryTreeNode * pRoot)
{
vector<vector<int> > result;
vector<int>temp;
queue<BinaryTreeNode * > que; //需要一個佇列
if(pRoot==NULL)
return result;
que.push(pRoot);
int nextLevel=0; //記錄層數
int toBeDeleted=1; //記錄當前待刪除的個數
while(!que.empty())
{
BinaryTreeNode *pNode=que.front();
temp.push_back(pNode->m_nValue);
if(pNode->m_pLeft)
{
que.push(pNode->m_pLeft);
nextLevel++; //nextLevel來記錄本行需要列印幾個值
}
if(pNode->m_pRight)
{
que.push(pNode->m_pRight);
nextLevel++;
}
que.pop();
--toBeDeleted;
if(toBeDeleted==0)
{
result.push_back(temp);
temp.clear();
toBeDeleted=nextLevel;
nextLevel=0;
}
return result;
}
}
八、將二叉搜尋樹變為有序的雙向連結串列(要求:不建立新節點,只調整指標)
//藉助vector和中序遍歷
vector<BinaryTreeNode *>temp;
void InOrderTraverseNode(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
return;
InOrderTraverseNode(pRoot->m_pLeft);
temp.push_back(pRoot);
InOrderTraverseNode(pRoot->m_pRight);
}
void ConvertBinaryTreeNodeToDoubleList(BinaryTreeNode * pRoot)
{
if(pRoot==NULL)
retrun ;
InOrderTraverseNode(pRoot);//中序遍歷,將值儲存到vector中
for(int i=0;i<temp.size()-1;++i)
temp[i]->m_pRight=temp[i+1];
temp[temp.size()-1]->m_pRight=NULL; //最後一個右節點指向為空
for(int j=temp.size()-1;j>0;j--)
temp[j]->m_pLeft=temp[j-1];
temp[0]->m_pLeft=NULL;
}
九、判斷二叉樹是否相同
bool StructureCmp(BinaryTreeNode *pRoot1,BinaryTreeNode *pRoot2)
{
if(pRoot1==NULL&&pRoot2==NULL)
return true;
if(pRoot1===NULL || pRoot2==NULL)
return false;
bool left=StructureCmp(pRoot1->m_pLeft,pRoot2->m_pLeft);
bool right=StructureCmp(pRoot1->m_pRight,pRoot2->m_pRight);
return left &&right;
}
十、判斷二叉樹是否是平衡二叉樹
bool IsAVL(BinaryTreeNode * pRoot, int & height)
{
if(pRoot==NULL)
{
height=0;
return true;
}
int left,right;
bool resultleft=IsAVL(pRoot->m_pLeft,left);
bool resultright=IsAVL(pRoot->m_pRight,right);
if(resultleft&&resultright&&abs(left-right)<=1)
{
height=max(left,right)+1;
return true;
}
else
{
height=max(left,right)+1;
return false;
}
}
參考了牛客網和其他大神的部落格,如有錯誤,請大家批評指正,謝謝,未完待續….