9.0树与二叉树基础算法

#include <cstdio>
#incldue <queue>
#include <stack>
using namespace std;
//二叉树
 
struct node{
	typename data;
	node* lchild;
	node* rchild;
};
node *root=NULL;

//1建立新结点,v为结点权值
node * newnode(int v)
{
	node *Node =new node; //申请一个node型变量的地址空间
	Node ->data=v; //结点权值为v 
	Node->lchild=Node->rchild=NULL; //初始状态下没有左右孩子 
	return Node; //返回新建结点的地址 
}

//2查找、修改算法 
void search(node* root,int x,int newdata)
{
	if(root==NULL)
	{
		return ;//空树,死胡同 
	}
	if(root->data==x) //找到数据域为x的结点,修改为newdata 
		root->data=newdata; 
 	search(root->lchild,x,newdata); //往左子树搜索,递归式 
	search(root->rchild,x,newdata); // 往右子树搜索,递归式 
 }

//3.插入一个数据域为x的结点 
void insert(node* &root,int x)//注意根结点指针root要用引用,否则插入不会成功 
{
	if(root==NULL)//空树,查找失败,也即插入位置(递归边界) 
	{
		root=newnode(x);
		return;
	}
	if(由二叉树的性质,x应该插在左子树)
	{
		insert(root->lchild,x);//往左子树搜索(递归式) 
	}
	else
	{
		insert(root->rchild,x);//往右子树搜素(递归式) 
	}	 
 }

//4.二叉树的建立
void create(int data[],int n)
{
	node* root=NULL; //新建空根结点root 
	for(int i=0;i<n;++i)
	{
		insert(root,data[i]);
	}
	return root;
 } 

//9.2二叉树的遍历
//1.先(根)序遍历
void preorder(node *root)
{
	if(root==NULL) //空树,返回,递归边界 
		return ;
	//访问根节点,例如将其数据域输出
	printf("%d\n",root->data);
	preorder(root->lchild);//递归式,访问左子树 
	preorder(root->rchild); 
 }

//2.中序遍历
void inorder(node *root)
{
	
	if(root==NULL)
		return ;
	inorder(root->lchild);
	printf("%d\n",root->data);//访问根节点root,例如将其数据域输出 
	inorder(root->rchild);
 } 
 
 //3.后续遍历
 void postorder(node* root) 
 {
 	if(root==NULL)
 		return;
 	postorder(root->lchild);
 	postorder(root->rchild);
 	printf("%d\n",root->data);
 }
 
 //4.层次遍历
 void layerorder(node *root)
 {
 	queue<node*> Q;//注意队列里是存地址!(队列中存放的是原来元素的一个副本,固需要修改队列中元素时
	 			   //若为queue<node> q,则修改的说副本中的元素,无法修改原来元素的值,故此处宜用指针! 
 	Q.push(root);
 	
 	while(!Q.empty())
 	{
 		node* p=Q.front();
 		printf("%d\n",p->data);
 		Q.pop();
 		if(p->lchild!=NULL)
 			Q.push(p->lchild);
 		if(p->rchild!=NULL)
 			Q.push(p->rchild);
	}
}

//注:有些题目需要计算结点的层数,固需在结构体中添加layer域
 struct node{
	typename data;
	node* lchild;
	node* rchild;
	int layer;
}Node;
//层次遍历记录层次
void layerOrder(Node*root)
{
	queue<node*>q;//注意这里存储的是地址 
	root->layer=1; //根节点的层次为1 
	q.push(root);
	while(!q.empty())
	{
		node *p=q.front();
		q.pop();
		printf("%d ",p->data);
		if(p->layer!=NULL) 
		{
			p->lchild->layer=p->layer+1;
			q.push(p->lchild);
		}
		if(p->rchild!=NULL)
		{
			p->rchild->layer=p->layer+1;
			q.push(p->rchild);
		}
	 } 
}

//给定一棵二叉树的先序遍历和中序遍历序列,插件这棵树
//当前先序序列区间为[preL,preR],中序序列区间为[intL,intR],返回根节点地址
node * create(int preL,int preR,int inL,int inR)
{
	if(preL>preR)
		return NULL;
	node* root=new node;//创建根结点 
	root->data=pre[preL];
	int k;
	for(k=inL;in[k]!=pre[preL];k++) //在中序序列中找到in[k]==pre[L]的结点 
		;
		
	int numleft=k-inL; //左子树的结点个数 
	
	//左子树的先序区间为[preL+1,preL+numleft],中序区间为[inL,k-1];
	//返回左子树的根节点地址,赋值给根节点的左指针
	root->lchild=create(preL+1,preL+numleft,inL,k-1);
	
	//右子树的先序区间为[preL+numleft+1,preR],中序区间为[k+1,inR];
	//返回右子树的根节点地址,赋值给根节点的右指针
	root->rchild=create(preL+numleft+1,preR,k+1,inR);
	
	return root; 
 } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值