zoukankan      html  css  js  c++  java
  • 面试题5:重建二叉树

    思路:先根据先序序列第一个数建立根节点,然后再中序序列中找到根节点的位置,进而确定左右子树的前序序列和后序序列,递归的构建左右子树。

    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;
    }
    


  • 相关阅读:
    如何查看openssl支持的所有TLS/SSL版本
    讲故事,学(AHK)设计模式—观察者模式
    React Hooks 详解 【近 1W 字】+ 项目实战
    为什么要在函数组件中使用React.memo?
    js防抖函数
    JS 深度优先遍历与广度优先遍历 实现查找
    你不知道的 requestIdleCallback
    RE:ゼロから始める文化課生活
    开学考小记 & 新生活的开始
    JS中:数组和对象的区别,以及遍历数组和遍历对象的区别
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3201420.html
Copyright © 2011-2022 走看看