二叉树

5676: 数据结构实验:二叉树遍历(顺序存储结构)

给定顺序存储的二叉树,要求输出遍历该二叉树得到的先序、中序、后序遍历序列。

二叉树的顺序存储是指用一组地址连续的存储单元依次自上而下、自左向右存储完全二叉树上的结点元素(一般二叉树则将其每个结点与完全二叉树上的结点对照)。

部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码。

int main()
{
int data;
n = 1;//下标从1开始
while(scanf("%d", &data), data!=-1)
{
tree[n++] = data;
}
PreOrder(1);
printf("\n");
InOrder(1);
printf("\n");
PostOrder(1);
printf("\n");
return 0;
}

输入

输入为若干个整数(不超过512)表示一棵二叉树顺序表示时的结点元素值,其中0表示二叉树对应结点为空。输入以-1结束。

输出

输出二叉树的先序、中序、后序遍历序列,每个序列占一行,每个元素之前空一格。

样例输入

1 2 3 4 5 0 0 0 0 6 7 -1

样例输出

1 2 4 5 6 7 3
4 2 6 5 7 1 3
4 6 7 5 2 3 1

代码

#include<stdio.h>
int tree[520],n;
void PreOrder(int x)
{
  if(x<=n&&tree[x]!=0)//结点编号有效并且不是空结点
  {
  printf(" %d",tree[x]);
  PreOrder(2*x);
  PreOrder(2*x+1);
  }
} 
void InOrder(int x)
{
 if(tree[x]!=0&&x<=n)
 {
 	InOrder(2*x);
 	printf(" %d",tree[x]);
 	InOrder(2*x+1);
 }   	
    	
}
void PostOrder(int x)
{
 if(tree[x]!=0&&x<=n)
 {
 	PostOrder(2*x);
 	PostOrder(2*x+1);
	printf(" %d",tree[x]);
 } 	
}
int main()
{
	int data;n=1;
	while(scanf(" %d",&data),data!=-1)
	{
		tree[n++]=data;
	}
    PreOrder(1);
    printf("\n");
    InOrder(1);
    printf("\n");
    PostOrder(1);
    printf("\n");
    return 0;
}

5411: 数据结构:二叉树高度(顺序存储)

描述

给定顺序存储的二叉树,求二叉树的高度。
二叉树的顺序存储是指用一组地址连续的存储单元依次自上而下、自左向右存储完全二叉树上的结点元素(一般二叉树则将其每个结点与完全二叉树上的结点对照)。
部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码。

int main()
{
int tree[512], n = 0;
int data;
while(scanf("%d", &data), data!=-1)
{
tree[n++] = data;
}
printf("%d\n", Height(tree, n));
return 0;
}

输入

输入为若干个整数(不超过512)表示一棵二叉树顺序表示时的结点元素值,其中0表示二叉树对应结点为空。输入以-1结束。

输出

输出二叉树的高度。

样例输入

1 2 3 4 5 0 0 0 0 6 7 -1

样例输出

4

#include<stdio.h>
int hh(int tree[],int n,int i)//用来求左右树的最大高度 
{
	if(i>=n||tree[i]==0)  //数据超出或者数据不存在就返回 
	return 0;
	int left=hh(tree,n,2*i+1);
	int right=hh(tree,n,2*i+2);    
	if(left>right)
	return left+1;
	else 
	return right+1;
}
int Height(int tree[],int n)
{
  return hh(tree,n,0);
}
int main()
{
    int tree[512], n = 0;  //这里定义了树的第一下标是0,所以左右孩子分别是2*i+1,2*i+2; 
    int data;
    while(scanf("%d", &data), data!=-1)
    {
    	tree[n++]=data;        //创建顺序树。就是读入数组了。 
    }
    printf("%d\n", Height(tree, n));
    return 0;
}

4405: 二叉树遍历(链式存储)

描述

给定一颗二叉树,要求输出遍历该二叉树得到的先序中序后序遍历序列。本题假设二叉树的结点数不超过1000。

输入

输入数据分为多组,第一行是测试数据的组数n,下面的n行分别代表一棵二叉树。每棵二叉树的结点均为正整数,数据为0代表当前结点为空,数据为-1代表二叉树数据输入结束,-1不作处理。二叉树的构造按照层次顺序(即第1层1个整数,第2层2个,第3层4个,第4层有8个…,如果某个结点不存在以0代替)

输出

输出每棵二叉树的先序、中序、后序遍历序列,每个序列占一行。

样例输入

2
1 -1
1 2 3 4 5 0 6 -1
样例输出

提示

1
1
1
1 2 4 5 3 6
4 2 5 1 3 6
4 5 2 6 3 1

输出的每个节点值前有一个空格。

#include<stdio.h>
#include<stdlib.h>
typedef struct Bitnode
{
	int data;
    struct Bitnode *left,*right;	
}Bitnode;
Bitnode *a[1003];
Bitnode *CreatBitree_level()
{
	Bitnode *head=NULL;
	int x,front=0,tail=0;
	while(scanf("%d",&x),x!=-1)
	{
		Bitnode *p=(Bitnode*)malloc(sizeof(Bitnode));
		if(x==0) p=NULL;
		else
		{
			p->data=x;
			p->left=p->right=NULL; 
		}
		a[tail++]=p;
		if(tail==1) head=p;
		else
		{
			if(p!=NULL&&a[front]!=NULL)
			{
				if(tail%2==0)
				a[front]->left=p;
				else
				a[front]->right=p;
			}
	      	if(tail%2==1)
		    front++;
			
		}
	
	}
	return head;
}
void xian(Bitnode *t)
{
	if(t==NULL)
	return;
	printf(" %d",t->data);
	xian(t->left);
	xian(t->right);
}
void zhong(Bitnode *t)
{
	if(t==NULL)
	return;	
	zhong(t->left);
	printf(" %d",t->data);
	zhong(t->right);
}
void hou(Bitnode *t)
{
	if(t==NULL)
	return;
    hou(t->left);
	hou(t->right);	
	printf(" %d",t->data);
}
int main()
{
	Bitnode *t;
	int n;
	scanf("%d",&n);
	while(n--)
	{
		t=CreatBitree_level();
		xian(t);
		printf("\n");zhong(t);
		printf("\n");
		hou(t);
		printf("\n");
	}
	return 0;
} 

5677: 数据结构实验:二叉树线索化

描述

二叉树遍历时,需要多次的压栈和出栈过程,效率比较低。对二叉树进行线索化可以有效解决此问题。
每一棵二叉树上,很多结点都含有未使用的指向NULL的指针域。二叉树线索化时:
如果结点有左子树,则 left 指针域指向左孩子,否则 left 指针域指向该结点的直接前趋;
如果结点有右子树,则 right 指针域指向右孩子,否则 right 指针域指向该结点的直接后继。
为了避免指针域指向的结点的意义混淆,需要改变结点本身的结构,增加两个标志域,最终结构如下:
typedef struct BNode
{
int data;
struct BNode* left, right;
int lTag, rTag;//0表示有孩子,1表示无孩子
}BNode;
后台已经完成了二叉树的创建,以及对线索化后的二叉树进行中序遍历。你需要补充完成二叉树中序线索化函数:
void InThreading(BNode
p);//主函数会调用此函数并将p指向根节点

输入

单组数据,占一行,代表一棵二叉树。结点均为正整数,数据为0代表当前结点为空,数据为-1代表二叉树数据输入结束,-1不作处理。二叉树的构造按照层次顺序(即第1层1个整数,第2层2个,第3层4个,第4层有8个…,如果某个结点不存在以0代替)。

输出

输出中序遍历二叉树得到的序列,每个结点之前空一格。

样例输入

1 2 0 3 4 -1

样例输出

3 2 4 1

全部代码

#include<stdio.h>
#include<stdlib.h>
typedef struct BNode
{
int data;
struct BNode* left, *right;
int lTag, rTag;//0表示有孩子,1表示无孩子
}BNode;
 BNode *a[1001];
 BNode *pre=NULL;
 BNode *CreatBitree_level()
{
  int x;
  BNode *head=NULL;
  int front=0,tail=0;
  while(scanf("%d",&x),x!=-1)
  {
  	BNode *p=(BNode*)malloc(sizeof(BNode));
  	if(x==0) p=NULL;
  	else
  	{
	  p->data=x;
	  p->left=p->right=NULL;	
	  }
	  a[tail++]=p;
	  if(tail==1) head=p;
	  else
	  {
  		if(a[front]!=NULL&&p!=NULL)
		  	{
		  	if(tail%2==0)
		  	a[front]->left=p;
		  	else
		  	a[front]->right=p;
	         }
		if(tail%2==1)
		front++;
		  
  	}
  }	
  return head;
}
 void InThreading(BNode *p)//核心部分,二叉树线索化 
 {
 	
 	if(p==NULL)     //空结点返回 
 	return ;
    InThreading(p->left);    
 	
	 if(p->left==NULL)    //左孩子为空时,指向前驱,左孩子为1 。左孩子p操作,右孩子pre操作 
 	 {
	 	p->left=pre;
	    p->lTag=1;	 	
	 }
	 if(pre!=NULL && pre->right==NULL) //前驱存在并且右孩子为空,指向后继,右孩子为1 
	 {
 		pre->right=p;
 		pre->rTag=1;
 	 }
     pre=p;
 	 InThreading(p->right);
  	
 }
 void InOrderThread(BNode* p)//中序遍历输出 
{
     while(p)
     {
      while(p->lTag==0)
      p = p->left;
      printf(" %d", p->data);
       while(p->rTag==1 && p->right!=NULL)
       {
       p = p->right;
       printf(" %d", p->data);
       }
       p = p->right;
      }
}
int main()
{
	BNode *t;
	t=CreatBitree_level();
	InThreading(t);
	InOrderThread(t);
		printf("\n");
	
	return 0;
}

5417: 数据结构实验:二叉树A+B

描述

给定两棵二叉树,将两棵树相同位置的结点值相加作为新结点,如果某棵树结点为空,则使用非空的结点作为新结点。

例如:

后台已经定义了以下类型:

struct TreeNode {

int val;

struct TreeNode *left;

struct TreeNode *right;

};

其它代码后台已经全部完成,您只需实现并提交以下函数:

struct TreeNode* mergeTrees(struct TreeNode* t1, struct TreeNode* t2);

输入

输入包括2行,每行描述一棵二叉树,使用若干个整数(不超过512)表示一棵二叉树顺序表示时的结点元素值,其中0表示二叉树对应结点为空。输入以-1结束。

输出

输出为二叉树的中序遍历结果,空格隔开。

样例输入

1 3 2 5 -1
2 1 3 0 4 0 7 -1

样例输出

5 4 4 3 5 7

#include<stdio.h>
#include<stdlib.h>
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
TreeNode *a[1005];
TreeNode *CreatBitree_level()
{
	TreeNode *head=NULL;
	int x,front=0,tail=0;
	while(scanf("%d",&x),x!=-1)
	{	
	    TreeNode *p=(TreeNode*)malloc(sizeof(TreeNode));
		if(x==0)
		p=NULL;
		else
		{
			p->val=x;
			p->left=p->right=NULL;
		}
		a[tail++]=p;
		if(tail==1) head=p;
		else
		{
			if(a[front]!=NULL&&p!=NULL)
			{
				if(tail%2==0)
				a[front]->left=p;
				else
				a[front]->right=p;
				
			}
			if(tail%2==1)
			front++;
		}
	}
	return head;
}
struct TreeNode* mergeTrees(struct TreeNode* t1, struct TreeNode* t2)//核心代码
{
	if(!t1)
	return t2;
	if(!t2)
	return t1;
    t1->val+=t2->val;
	t1->left=mergeTrees(t1->left,t2->left);
	t1->right=mergeTrees(t1->right,t2->right);	
    return t1;
}
void dayin(TreeNode*t3)
{
	if(!t3)
	return;
	dayin(t3->left);
	printf("%d ",t3->val);
	dayin(t3->right);
}
int main()
{
	TreeNode*t1=CreatBitree_level(),*t2=CreatBitree_level();
	TreeNode*t3=mergeTrees(t1,t2);
	dayin(t3);
	return 0;
}

二叉排序树

#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
  int data;
  struct Node *left, *right;
}Node;
Node * CreateTree(int n)
{ 
	 int a[200],i;
	 for(i=0;i<n;i++)
	 scanf("%d",&a[i]);
	 Node *head;
	 head=(Node*)malloc(sizeof(Node));
 	 head->data=a[0];
 	 head->left=head->right=NULL;
 	 for(i=1;i<n;i++)
 	 {
 	 	Node *p=head,*q;
 	 	Node *tt=(Node*)malloc(sizeof(Node));
 	 	tt->data=a[i];
 	 	tt->left=tt->right=NULL;
 	 	while(p)
 	 	{
	 	    q=p;
	 	 	if(a[i]<p->data)
	 	 	p=p->left;
	 	 	else
	 	 	p=p->right;
	 	 }	
		if(a[i]<q->data)
		q->left=tt;
		else
		q->right=tt; 
 	 }
	 return head;
}

void inorder(Node *t)
{
	if(t)
	{
		inorder(t->left);
		printf(" %d",t->data);
		inorder(t->right);
	}
}
int main()
{
	Node *t;
	int n;
	while(~scanf("%d",&n))
	{
	   t=CreateTree(n);
	   inorder(t);	
	   printf("\n");
	}

	return 0;
} ```

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值