面试训练树的性质

插入一条很重要的概念


现在看了下海涛的题目

基于两种遍历结构 重建二叉树,应该不难

前序遍历从根开始,然后依次左节点,右节点。类似堆的建立过程中的差不多,可以说是深度优先遍历吧

中序遍历从左子树 到根,然后 到右子树, 这个性质在二叉排序树中很有用,数组递增排列

把思路理一下

1 根结点 -----------》4 7 2左子树  5 3 8 6 右子树

2 左子树根结点------------》4 7左子树

4 左子树根结点---------》7为其右孩子

这个思路这么看着还是有规律的,感觉可以用递归做。试试吧

#include "stdio.h"
typedef  int MYTYPE;

typedef struct Node{
	int data;
	struct Node *left;
	struct Node *right;
} LNode;
void buildTree(LNode **head,int *data1,int *data2,int start,int end,int start1,int end1)
{
	int i=0;
	LNode *p=NULL;
	if(start >end || start1 >end1)
	{
		return;
	}
	
	p = (LNode *)malloc(sizeof(LNode));
	p->data =data1[start];
	p->left = NULL;
	p->right = NULL;
	*head = p;
	
	for(i=start1;data1[start] != data2[i];i++)
	{
	
	}
	i=i-start1;
	buildTree(&(p->left),data1,data2,start+1,start+i,start1,start1+i-1);
	buildTree(&(p->right),data1,data2,start+i+1,end,start1+i+1,end1);
	
}
void traverse(struct Node *root)
{
	if(root==NULL)
	{
		return;
	}
	traverse(root->left);
	traverse(root->right);
	printf("%d ",root->data);
}
int main()
{
	int data1[] = {1,2,4,7,3,5,6,8};/*pre*/
	int data2[]= {4,7,2,1,5,3,8,6}; /*mid*/
	LNode *head = NULL;
	buildTree(&head,data1,data2,0,8-1,0,8-1);
	traverse(head);
	return 0;
}

这个思路一会分析下~

采用递归 前序遍历第一个节点为根结点,那么我们在中序遍历中找相应的节点,如果相等,那么该节点左边为左子树,右边为右子树。

那么下面左子树的建立,和右子树的建立性能 和根结点的建立相同,所以可以用递归来实现

算法时间复杂度  T(n) = 2T(n/2)+O(n)

根据主定理nlogn


非递归以及递归中序遍历二叉树

#include "iostream"
#include "stack"
using namespace std;

typedef struct Node{  
    int data;  
    struct Node *left;  
    struct Node *right;  
} LNode;  

void buildTree(LNode **head)  
{  
    int i=0;  
	int data;
	
    LNode *p=NULL;  
    scanf("%d",&data);
	if(data==-1)
	{
		head=NULL;
	}
	else
	{
		p = (LNode *)malloc(sizeof(LNode));  
		p->left = NULL;  
		p->right = NULL;  
		p->data=data;
		*head = p; 
		 buildTree(&((*head)->left));  
		 buildTree(&((*head)->right));  
	}	     
      
}  
void traverseTree(LNode *p)
{
	if(p == NULL)
		return;
		
	traverseTree(p->left);
	printf("%d ",p->data);
	traverseTree(p->right);
}
void traverseStack(LNode *p)
{
	stack<LNode *> myStack;
	LNode *q=NULL;
	myStack.push(p);
	while(!myStack.empty())
	{
		while((q=myStack.top())&&q)
		{
			myStack.push(q->left);
		}
		myStack.pop();
		if(!myStack.empty())
		{
			q =myStack.top();
			if(q)
				printf("%d ",q->data);
			myStack.pop();
			myStack.push(q->right);
		}
	

	
	}
}
int main()
{
	LNode *head=NULL;
	buildTree(&head);
	traverseTree(head);
	putchar('\n');
	traverseStack(head);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值