数组数据构建二叉树

本文介绍了如何通过C语言将一维数组中的数据按照二叉树层次结构构建节点,并生成链表。通过节点地址转换函数递归地创建节点,最后通过后序遍历验证链表的正确性。
摘要由CSDN通过智能技术生成

1、数组数据说明

数组中的数据是按照二叉树的层次存放的,位置上没有数据的放NULL.

比如:

int a[] = {5,1,4,NULL,NULL,3,6};

2、数组数据构建二叉树

2.1、构建节点

如上图,节点需要一个结构体指针成员指向左孩子

          一个结构体指针成员指向右孩子

          一个成员存储数据

typedef struct node
{
	struct node *lchild;   // 指向左孩子指针
	int data;            // 存储数据
	struct node *rchild;   // 指向右孩子指针
}NODE;

2.2、生成链表

1、获取数组中数据构造的二叉树的层次

每个节点最多有两颗子树的树称为 二叉树。

数组中的数据按照1生2,2生4......的规则构造二叉树

数组元素总个数 <= 2^0+2^1+2^2+......2^n = 2^(n+1)-1

所以,二叉树的层次 = 向下取整( log2(数组元素总个数) )

2、构造链表

按照上一步求出的层次,生成新节点放置数组中的数据。

由上图可以看出此二叉树和对应的一维数组中的索引值有以下关系:

        1、左子树的索引值是父节点的索引值乘2。

        2、右子树的索引值是父节点的索引值乘2加1。

注意:

        为了方便使用索引是从1开始的,但是数组下标要从0开始。

        已知索引求当前索引对应数据在二叉树的第几层: 向下取整( log2(索引) )即可。

思路:
  
 节点地址 转换函数(数组,索引,长度)
    {
        获取二叉树的层次
        获取当前索引 在第几层
        
        如果索引对应数组数据 == NULL 或者 索引 > 长度
        {
            返回 NULL 结束
        }        
        否则
        {
            创建节点
            将索引对应的数组数据写入节点data中
            
            如果 当前是最后一层节点
            {
                将节点的左右孩子设置为NULL
            }
            否则
            {
                // 添加下一级左右孩子
                节点->lchild = 转换函数(数组,2*索引,长度);
                节点->rchild = 转换函数(数组,2*索引+1,长度);
            }
            
            最后返回节点地址
        }        
    }

代码:

        

// 根据数组生成链表并将头结点的地址返回 
NODE *makeLink(int arr[],int idx,int size)
{	
    // 二叉树的层次
	static int fNum;   
	fNum = bBinaryTreeFloor(size);	
	
	// 根据下标求当前节点在第几层 -- 对数 
	int nfloor = (int)floor(log2(idx));  
	
	// 如果数组元素值为NULL或者节点在数组中没有 左孩子或者右孩子了 
	if(arr[idx-1] == NULL || idx > size)
	{
		return NULL;
	}
	
	// 创建节点
	NODE *p = (NODE *)malloc(sizeof(NODE));
	// 添加节点数据 
	p->data = arr[idx-1];	
	 
	if(nfloor == fNum - 1) 
	{		
		// 如果是最后一层的节点即叶子节点则左右孩子指针为NULL 
		p->lchild = NULL;
		p->rchild = NULL; 
	} 
	else
	{		
		// 继续向下添加左孩子 
		p->lchild = makeLink(arr,2*idx,size);		
		// 继续向下添加右孩子 
		p->rchild = makeLink(arr,2*idx+1,size); 		
	}		
	
	// 将节点地址返回给它父亲的左右指针 
	return p;
}

3、遍历二叉树验证

二叉树的编译可以参考:二叉树遍历C语言实现

本例使用后序遍历进行检测构造的链表是否完好。

int main()
{
	NODE *root = NULL;
	// int a[] = {2,1,3};
	int a[] = {5,1,4,NULL,NULL,3,6};
	int len = sizeof(a) / sizeof(int);	
	
	root = makeLink(a,1,len);	
	postOrder(root);
	
	return 0;
}

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小镇做题家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值