二叉樹經典面試題

二叉樹的結點類型如下:

typedef struct BtNode
{
    BtNode *leftchild;
    BtNode *rightchild;
    ElemType data;
}BtNode, *BinaryTree;

1. 給你一顆普通的二叉樹,求二叉樹中最遠的兩個節點的距離

   分析:

   1、如果具有最遠距離的兩個結點之間的路徑經過根結點,則最遠距離就是這個根節點左邊的深度加上根節點的右邊的深度。

  2、如果具有最遠距離的兩個結點之間的路徑不經過根節點,則最遠距離的結點就在根節點的某一棵子樹上的兩個葉子結點。

  使用distance記錄這個最遠的距離。後序遍歷二叉樹中每一個結點,對於每一個結點先算出左邊和右邊的深度和然後與distance裏面的數據進行比較,如果結果大於distance則更新distance的值。

int _GetFarDistance(BtNode* root,int &distance)
{
	if(root==NULL) return 0;
	int Left=_GetFarDistance(root->_left,distance);
	int Right=_GetFarDistance(root->_right,distance);
	if((Left+Right)>distance)
	{
		distance=Left+Right;
	}
	return Left>Right?Left+1:Right+1;
}


int GetFartherDistance(BtNode* root)
{
	assert(root);
	int distance=0;
	_GetFarDistance(root,distance);
	return distance; 
}

2. 由前序遍歷和中序遍歷重建二叉樹(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)

  前序遍歷的每一結點,都是當前子樹的根節點,我們可以根據前序遍歷的序列對中序遍歷的序列進行劃分。


int IsIndex(ElemType *is,ElemType x,int n)
{
	for (int i = 0;i<n;++i)
	{
		if (is[i] == x)
		{
			return i;
		}
	}
	return -1;
}
 
BtNode * CreatePI(ElemType *ps,ElemType *is,int n)
{
	BtNode *s = NULL;
	if (n > 0)
	{
		s = BuyNode();
		s->data = ps[0];
		int pos = IsIndex(is,ps[0],n);
		if (pos == -1)
		{
			exit(1);
		}
		s->leftChild = CreatePI(ps+1,is,pos);
		s->rightChild = CreatePI(ps+pos+1,is+pos+1,n-pos-1);
	}
	return s;
}
BtNode * CreateTreePI(ElemType *ps,ElemType *is,int n)
{
    if (ps == NULL || is == NULL || n < 1)
    {
        return NULL;
    }
    else
    {
        return  CreatePI(ps,is,n);
    }
}

3. 判斷一棵樹是否是完全二叉樹

我們可以根據完全二叉樹的定義,按照層序遍歷一顆樹,當遇到空結點時如果這棵樹已經遍歷完畢,則這棵樹就是完全二叉樹,如果遇到空結點的後面還有元素則這棵樹就不是完全二叉樹。

bool IsCompleteBinaryTree(BTNode* root)  //判斷一顆二叉樹是否是完全二叉樹
{
	if (root == NULL)
		return false;
	queue<BTNode*> q;
	int flag = 0;
	q.push(root);
	while (!q.empty())
	{
		BTNode<int>* cur = q.front();
		q.pop();
		if (cur->_left)
		{
			if (flag)
				return false;
			q.push(cur->_left);
		}
		else
		{
			if (flag == 0)
				flag = 1;
		}
		if (cur->_right)
		{
			if (flag)
				return false;
			q.push(cur->_right);
		}
		else
		{
			if (flag == 0)
				flag = 1;
		}
	}

方法2:

        

什麼是完全二叉樹呢???

  如果一顆二叉樹的只有最後兩層結點的度能小於2,其餘結點的度都等於2。且最後一層的結點從最左邊依次排列。

思路:  若父節點不空,我們將二叉樹左右孩子依次放入隊列(空結點也放入隊列),依次出隊,遇到第一個空結點,我們判斷後續隊列中的節點是否爲空,若空,則是完全二叉樹。

    

bool Is_Comp_BinaryTree(BtNode *ptr)
{
	if (ptr == NULL) return true;
	queue<BtNode *> qu;
	qu.push(ptr);
	while (!qu.empty())
	{
		BtNode *p = qu.front(); qu.pop();
		if (p == NULL)
		{
			break;
		}
		qu.push(p->leftchild);
		qu.push(p->rightchild);
	}
	while (!qu.empty())
	{
		BtNode *p = qu.front(); qu.pop();
		if (p != NULL) return false;
	}
	return true;
}

 

4. 後序和中序序列創建二叉樹 


int IsIndex(ElemType *is,ElemType x,int n)
{
	for (int i = 0;i<n;++i)
	{
		if (is[i] == x)
		{
			return i;
		}
	}
	return -1;
}
BtNode * CreateIL(ElemType *is,ElemType *ls,int n)
{
    BtNode *s = NULL;
    if (n > 0)
    {
        int pos = IsIndex(is,ls[n-1],n);
        if (pos == -1)
        {
            exit(1);
        }
        s = BuyNode();
        s->data = ls[n-1];
        s->leftChild = CreateIL(is,ls,pos);
        s->rightChild = CreateIL(is+pos+1,ls+pos,n-pos-1);
    }
    return s;
}
BtNode * CreateTreeIL(ElemType *is,ElemType *ls,int n)
{
    if (is == NULL || ls == NULL || n < 1)
    {
        return NULL;
    }
    else
    {
        return CreateIL(is,ls,n);
    }
}

5. 求兩個節點的最近公共祖先

分析:

  求兩個結點的最近公共祖先有兩種情況。

  1、如果這兩個結點不在一條線上,則它們就分別在最近的公共祖父的左右子樹上。

  2、如果這兩個結點在一條線上,則它們之中深度最前的就是他們的最近的公共祖先。

思路:

       給定一棵二叉樹的頭節點root,以及這棵二叉樹的兩個節點node1和node2,請返回node1和node2的最近公共祖先節點。我們可以後序遍歷這棵樹,用left記錄左子樹返回的結果,用right記錄右子樹返回的結果。

雖然是三種情況,但是不論是哪一種,只要返回left和right中不爲空的就可以了

BTNode* _GetAncestor(BTNode root,BTNode node1,BTNode node2)
{
	if (root == NULL)
		return NULL;
	BTNode left = _GetAncestor(root->_left, node1, node2);
	BTNode right = _GetAncestor(root->_right, node1, node2);
	if (left&&right)
		return root;
	if (root == node1)
		return node1;
	if (root == node2)
		return node2;
	if (left == NULL&&right)
		return right;
	if (right == NULL&&left)
		return left;
	return NULL;
}

BTNode* GetAncestor(BTNode* root, BTNode* node1, BTNode* node2)
{
	assert(root);
	assert(node1);
	assert(node2);
	BTNode* parent = NULL;
	BTNode* left = NULL;
	BTNode* right = NULL;
	parent = _GetAncestor(root, node1, node2);
	return parent;
	​
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章