二叉树的创建和遍历(前序,中序,后序,层序)

二叉树的单个结构就是中间是数据域两边分别对应着左子树的指针和右子树的指针;因此先定义二叉树的结构体:

typedef struct tree{
	int data; //数据域
	struct tree *lchild;
	struct tree *rchild;
	//左右子树的指针
}tree,*linktree;

二叉树的创建:
 

linktree creat(){//创建
	int data;
	linktree t;
	scanf("%d",&data);
	if (data ==-1)//输入-1就代表着没有子树
		return NULL;
	else{
		t=(linktree)malloc(sizeof(tree));
		t->data=data;
		printf("这个%d树的左子树是:",data);
		t->lchild=creat();//利用递归
		printf("这个%d树的右子树是:",data);
		t->rchild=creat();
		return t;
	}
}

前序遍历(根,左,右):

 

void xian(linktree t){
	if (t==NULL)
		return ;
	else{
		printf("%d\t",t->data);
		xian(t->lchild);
		xian(t->rchild);
	}
}

中序遍历(左,根,右):


 

void zhong(linktree t){
	if (t==NULL)
	{
		return ;
	}
	else
	{
		zhong(t->lchild);
		printf("%d\t",t->data);
		zhong(t->rchild);
	}
}

后序遍历(左 ,右,根 )

 

void hou(linktree t){
	if (t ==NULL)
	{
		return;
	}
	else{
		hou(t->lchild);
		hou(t->rchild);
		printf("%d\t",t->data);
	}
	
}

层序遍历啊(按照层次,要利用到队列):

 

void cen(linktree t){
	linktree a[100],p;
	int front,rear;//创建队列的指针
	if (t==NULL)
	{
		return ;
	}
	else{
		a[0]=t;
		front=-1;
		rear=0;
		while(front!=rear){//当对队列不是空就执行循环
			printf("%d\t",a[++front]->data);
			p=a[front];//p是当前树的指针
			if (p->lchild!=NULL)
			{
				a[++rear]=p->lchild;
			}
			if (p->rchild!=NULL)
			{
				a[++rear]=p->rchild;
			}
		}
	}
}

总的代码:

#include <stdio.h>
#include<stdlib.h>
typedef struct tree{
	int data; //数据域
	struct tree *lchild;
	struct tree *rchild;
	//左右子树的指针
}tree,*linktree;
linktree creat(){//创建
	int data;
	linktree t;
	scanf("%d",&data);
	if (data ==-1)//输入-1就代表着没有子树
		return NULL;
	else{
		t=(linktree)malloc(sizeof(tree));
		t->data=data;
		printf("这个%d树的左子树是:",data);
		t->lchild=creat();//利用递归
		printf("这个%d树的右子树是:",data);
		t->rchild=creat();
		return t;
	}
}
void xian(linktree t){
	if (t==NULL)
		return ;
	else{
		printf("%d\t",t->data);
		xian(t->lchild);
		xian(t->rchild);
	}
}
void zhong(linktree t){
	if (t==NULL)
	{
		return ;
	}
	else
	{
		zhong(t->lchild);
		printf("%d\t",t->data);
		zhong(t->rchild);
	}
}
void hou(linktree t){
	if (t ==NULL)
	{
		return;
	}
	else{
		hou(t->lchild);
		hou(t->rchild);
		printf("%d\t",t->data);
	}
	
}
void cen(linktree t){
	linktree a[100],p;
	int front,rear;//创建队列的指针
	if (t==NULL)
	{
		return ;
	}
	else{
		a[0]=t;
		front=-1;
		rear=0;
		while(front!=rear){//当对队列不是空就执行循环
			printf("%d\t",a[++front]->data);
			p=a[front];//p是当前树的指针
			if (p->lchild!=NULL)
			{
				a[++rear]=p->lchild;
			}
			if (p->rchild!=NULL)
			{
				a[++rear]=p->rchild;
			}
		}
	}
}
int main(){
	linktree t;
	printf("先输入根:");
	t=creat();
	printf("先序:");
	xian(t);
	printf("中序:");
	zhong(t);
	printf("后序:");
	hou(t);
	printf("层序:");
	cen(t);
}

代码测试:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
平衡二叉树(如AVL树或红黑树)是一种自平衡的数据结构,它的每个节点都维护了某种平衡性质,例如AVL树要求左右子树的高度差不超过1。在二叉链表(双向链表)上实现这样的树,我们需要定义一个节点结构,包含值、指向驱和后继节点的引用,以及用于平衡调整的指针。 首先,让我们定义一个基本的节点结构: ```cpp template <typename T> struct TreeNode { T value; TreeNode<T>* left; TreeNode<T>* right; TreeNode<T>* prev; // 链表驱节点 TreeNode<T>* next; // 链表后继节点 }; ``` 接下来,我们实现基本操作: 1. **建立平衡二叉树**: - 使用递归方式创建一个空的树或者插入一个新节点并调整平衡。 - 插入操作:先插入普通二叉链表,然后检查不平衡,进行相应的旋转(左旋、右旋)。 ```cpp void insert(TreeNode<T>& root, const T& value) { // ...插入过程,包括新节点的创建和调整 } ``` 2. **查找**: - 从根开始,比较目标值和当节点值,递归地在左或右子树查找。 ```cpp TreeNode<T>* find(TreeNode<T>& root, const T& value) { // ...查找过程,递归查找直到找到或遍完树 } ``` 3. **删除**: - 删除操作相对复杂,涉及三种情况(删除的节点无子节点、有一个子节点、有两个子节点),需要考虑保持平衡的同时更新驱和后继节点。 ```cpp void remove(TreeNode<T>& root, const T& value) { // ...删除过程,包括查找节点和处理删除后的平衡调整 } ``` 4. **销毁**: - 遍整个树,对每个节点调用析构函数,释放内存。 ```cpp void destroy(TreeNode<T>& root) { // ...遍树并销毁节点 } ``` 最后,**main函数** 测试: ```cpp int main() { // 初始化一棵平衡二叉树 TreeNode<int> root = buildBalancedTree(); // 测试插入、查找 int search_value = 10; if (auto found = find(root, search_value); found) { std::cout << "Found: " << found->value << std::endl; } else { std::cout << "Not found" << std::endl; } // 插入一个元素并验证平衡 insert(root, 20); // ... // 删除元素并验证平衡 remove(root, 10); // ... // 销毁并释放内存 destroy(root); return 0; } ``` 为了完整实现上述代码,还需要实现具体的旋转函数(左旋、右旋)、平衡判断函数等。由于这里篇幅有限,我只能给出核心思路。在实际编程,这些部分会更详细且复杂。如果你需要完整的代码示例,请告诉我,我可以提供更具体的代码片段。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值