劍指offer面試題:重建二叉樹(註釋很多)

       題目要求:輸入二叉樹前序遍歷和中序遍歷的結果,假設輸入的數字都不包含重複數字,構建出滿足序列的二叉樹。

       樹結構是我一直很頭疼的一部分,感覺他是數據結構中最繁瑣的了,如果我們要想學會這部分首先大家一定要明白樹的結構,以及前序遍歷,中序遍歷,後續遍歷的特點,還有就是腦子中有遞歸的概念。明白看這些特點我們再學樹就如魚得水了,廢話不多說,大家可以看看代碼,我把需要注意的地方都用註釋寫了下來,可能比較簡陋,有問題請大家指正。

#include <iostream>
#include<vld.h>
using namespace std;
struct Btnode
{
	int data;
	Btnode *left;
	Btnode* right;
};
Btnode* Constructnode(int *startpre,int *endpre,int *startin,int* endin);//函數聲明

Btnode* construct(int *pre,int *in,int length)
{
	if(pre==NULL || in==NULL || length<0)//判斷形參的合法性
	{
		return NULL;
	}
	return Constructnode(pre,pre+length-1,in,in+length-1);//構建二叉樹結構
}
Btnode* Constructnode(int *startpre,int *endpre,int *startin,int* endin)//形參爲前序序列和中序序列的開頭和結尾
{
	Btnode* root=new Btnode;//創建根節點
	int rootdata=startpre[0];//前序遍歷的順序爲根左右,所有第一個數字爲根
	root->data=rootdata;
	root->left=NULL;
	root->right=NULL;

	if(startpre==endpre)// 只有一個根節點,沒有左右孩子的情況
	{
		if(startin==endin && *startpre==*startin)
		{
			return root;
		}
		else//說明前序序列的輸入有問題
		{
			throw std::exception("輸入的序列有誤\n");
		}
	}
	int *rootin=startin;
	while(rootin<=endin&&*rootin!=rootdata)//找出中序遍歷根的所在位置
		rootin++;//rootin保存根節點在中序遍歷裏面的位置
	if(*rootin!=rootdata)//如果在中序遍歷中沒有找到說明中序序列輸入的序列有問題。
	{
		throw exception("輸入的序列有誤\n");
	}
	int leftnum=rootin-startin;//算出根節點的左孩子個數

	if(leftnum>0)//大於零說明有左孩子,所以要創建左孩子節點
	{
		root->left= Constructnode(startpre+1,startpre+leftnum,startin,rootin-1);//利用遞歸將規模縮小,將那些左孩子視爲一個二叉樹,然後前序序列中的第二個數字作爲新的根節點,傳入三個左孩子,中序序列則傳入前三個節點。
	}

	if(leftnum<endpre-startpre)//因爲輸入的序列長度=左孩子個數+右孩子個數,所以如果左孩子的個數小於序列的長度就說明存在右孩子。
	{
		root->right= Constructnode(startpre+leftnum+1,endpre,rootin+1,endin);//遞歸縮小規模,前序遍歷數組傳入後四個右孩子節點,中序遍歷數組傳入後四個有孩子節點
	}
	return root;
}

void remove(Btnode *root)//防止內存泄漏
{
	if(root==NULL)
	{
		return;
	}
	remove(root->left);
	remove(root->right);
	delete[] root;
}
int main()
{
	int n;
	printf("請輸入二叉樹的葉子數\n");
	scanf("%d",&n);
	int *pre=new int[n]();
	int *in=new int[n]();
    printf("請輸入前序遍歷的數字\n");
	for(int i=0;i<n;i++)
	{
		scanf("%d",&pre[i]);
	}
    printf("請輸入中序遍歷的數字\n");
	for(int j=0;j<n;j++)
	{
		scanf("%d",&in[j]);
	}
    Btnode *root=construct(pre,in,n);//創建完畢,查看root的左右孩子就可以看到二叉樹的結構
	remove(root);//最後別忘記內存泄漏喲
	delete[] pre;
	delete[] in;
	
}

 

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