程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 面試題5:重建二叉樹

面試題5:重建二叉樹

編輯:C++入門知識

\

思路:先根據先序序列第一個數建立根節點,然後再中序序列中找到根節點的位置,進而確定左右子樹的前序序列和後序序列,遞歸的構建左右子樹。

C++代碼:

 

#include "stdafx.h"   
#include <iostream>   
#include <assert.h>   
using namespace std;  
  
struct BiTreeNode  
{  
    int m_nData;  
    BiTreeNode *m_pLeftChild;  
    BiTreeNode *m_pRightChild;  
};  
  
BiTreeNode* CreateBiTreeByPreorderAndInorder(int* preOrder, int nPreStart, int nPreEnd,  
                                             int* inOrder, int nInStart, int nInEnd)  
{  
    //出口   
    if (nPreStart > nPreEnd)  
    {         
        return NULL;          
    }     
  
    //根據先序序列找到根結點   
    int nRootDate = preOrder[nPreStart];  
    //在中序序列中找到根結點   
    int nCount = 0;  
    int nCur = 0;  
    for (nCur=nInStart; nCur<=nInEnd; nCur++)  
    {  
        if (nRootDate != inOrder[nCur])  
        {  
            nCount++;//nCount記錄左子樹的結點個數   
        }  
        else  
        {  
            break;  
        }  
    }  
  
    assert(nCur >= nInStart && nCur <= nInEnd);     
      
    //創建結點   
    BiTreeNode* pRoot = new BiTreeNode;  
    pRoot->m_nData = nRootDate;    
    //根據中序序列,劃分兩個序列,遞歸處理。   
    pRoot->m_pLeftChild = CreateBiTreeByPreorderAndInorder(preOrder,nPreStart + 1,nPreStart + nCount  
                                                          ,inOrder,nInStart,nInStart + nCount - 1);  
    pRoot->m_pRightChild = CreateBiTreeByPreorderAndInorder(preOrder,nPreStart + nCount + 1,nPreEnd  
                                                          ,inOrder,nInStart + nCount + 1,nInEnd);  
  
    return pRoot;  
}  
  
//根據二叉樹的前序遍歷序列和後序遍歷序列重建二叉樹   
BiTreeNode * CreateBiTreeByPreorderAndInorder(int *preOrder, int *inOrder, int nLength)  
{  
    if ((preOrder!=NULL) && (inOrder!=NULL) && (nLength>0))  
    {  
        return CreateBiTreeByPreorderAndInorder(preOrder, 0, nLength-1, inOrder, 0, nLength-1);  
    }  
    else  
    {  
        return NULL;  
    }  
}  
  
void PreOrderPrint(BiTreeNode *pRoot)  
{  
    if (pRoot != NULL)  
    {  
        cout << pRoot->m_nData << " ";  
        PreOrderPrint(pRoot->m_pLeftChild);  
        PreOrderPrint(pRoot->m_pRightChild);  
    }     
}  
  
void InOrderPrint(BiTreeNode *pRoot)  
{  
    if (pRoot != NULL)  
    {         
        InOrderPrint(pRoot->m_pLeftChild);  
        cout << pRoot->m_nData << " ";  
        InOrderPrint(pRoot->m_pRightChild);  
    }     
}  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    int nPreOrderArr[8] = {1,2,4,7,3,5,6,8};  
    int nInOrderArr[8] = {4,7,2,1,5,3,8,6};  
    BiTreeNode *pRoot = CreateBiTreeByPreorderAndInorder(nPreOrderArr, nInOrderArr,8);  
  
    cout << "先序序列:";  
    PreOrderPrint(pRoot);  
    cout << endl;  
    cout << "後序序列:";  
    InOrderPrint(pRoot);  
    cout << endl;  
  
    system("pause");  
    return 0;  
}  
#include "stdafx.h"
#include <iostream>
#include <assert.h>
using namespace std;

struct BiTreeNode
{
	int m_nData;
	BiTreeNode *m_pLeftChild;
	BiTreeNode *m_pRightChild;
};

BiTreeNode* CreateBiTreeByPreorderAndInorder(int* preOrder, int nPreStart, int nPreEnd,
											 int* inOrder, int nInStart, int nInEnd)
{
	//出口
	if (nPreStart > nPreEnd)
	{		
		return NULL;		
	}	

	//根據先序序列找到根結點
	int nRootDate = preOrder[nPreStart];
	//在中序序列中找到根結點
	int nCount = 0;
	int nCur = 0;
	for (nCur=nInStart; nCur<=nInEnd; nCur++)
	{
		if (nRootDate != inOrder[nCur])
		{
			nCount++;//nCount記錄左子樹的結點個數
		}
		else
		{
			break;
		}
	}

	assert(nCur >= nInStart && nCur <= nInEnd);	
	
	//創建結點
	BiTreeNode* pRoot = new BiTreeNode;
	pRoot->m_nData = nRootDate;	
	//根據中序序列,劃分兩個序列,遞歸處理。
	pRoot->m_pLeftChild = CreateBiTreeByPreorderAndInorder(preOrder,nPreStart + 1,nPreStart + nCount
		                                                  ,inOrder,nInStart,nInStart + nCount - 1);
	pRoot->m_pRightChild = CreateBiTreeByPreorderAndInorder(preOrder,nPreStart + nCount + 1,nPreEnd
		                                                  ,inOrder,nInStart + nCount + 1,nInEnd);

	return pRoot;
}

//根據二叉樹的前序遍歷序列和後序遍歷序列重建二叉樹
BiTreeNode * CreateBiTreeByPreorderAndInorder(int *preOrder, int *inOrder, int nLength)
{
    if ((preOrder!=NULL) && (inOrder!=NULL) && (nLength>0))
    {
		return CreateBiTreeByPreorderAndInorder(preOrder, 0, nLength-1, inOrder, 0, nLength-1);
    }
	else
	{
		return NULL;
	}
}

void PreOrderPrint(BiTreeNode *pRoot)
{
	if (pRoot != NULL)
	{
		cout << pRoot->m_nData << " ";
		PreOrderPrint(pRoot->m_pLeftChild);
		PreOrderPrint(pRoot->m_pRightChild);
	}	
}

void InOrderPrint(BiTreeNode *pRoot)
{
	if (pRoot != NULL)
	{		
		InOrderPrint(pRoot->m_pLeftChild);
		cout << pRoot->m_nData << " ";
		InOrderPrint(pRoot->m_pRightChild);
	}	
}

int _tmain(int argc, _TCHAR* argv[])
{
	int nPreOrderArr[8] = {1,2,4,7,3,5,6,8};
	int nInOrderArr[8] = {4,7,2,1,5,3,8,6};
	BiTreeNode *pRoot = CreateBiTreeByPreorderAndInorder(nPreOrderArr, nInOrderArr,8);

	cout << "先序序列:";
	PreOrderPrint(pRoot);
	cout << endl;
	cout << "後序序列:";
	InOrderPrint(pRoot);
	cout << endl;

	system("pause");
	return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved