二叉树递归操作大全(前序、中序、后序、层序遍历、二叉树的创建、节点、叶子节点和第k层节点个数、判断是否为完全二叉树)

在完成二叉树里面的操作时得先明白二叉树的概念,二叉树有两种情况:

1、空树

2、根节点 + 根节点的左子树 + 根节点的右子树 (这里的左子树和右子树又是一颗二叉树)

可以看出在定义二叉树的时候就是用递归的方式定义的,后面的操作大多也都用到这样的思想。

一、二叉树的遍历

 

1、前序遍历

规则:访问根节点 --> 前序遍历左子树 --->前序遍历右子树

代码:

void BinaryTreePrevOrder(BTNode* root) {
	if (root == NULL) {
		return;
	}
	printf("%d ", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}

对上图来说,遍历的结果为1、2、3、4、5、6,具体情况如下:

 2、中序遍历

规则:中序遍历左子树 ----> 访问根节点 ------>  中序遍历右子树

代码:

void BinaryTreeInOrder(BTNode* root) {
	if (root == NULL) {
		return;
	}
	BinaryTreeInOrder(root->_left);
	printf("%d ", root->_data);
	BinaryTreeInOrder(root->_right);
}

对上图来说遍历结果为3、2、1、5、4、6。

3、后序遍历

规则:后序遍历左子树---->后序遍历右子树---->访问根节点

代码:

void BinaryTreePostOrder(BTNode* root) {
	if (root == NULL) {
		return;
	}
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%d ", root->_data);
}

对上图的遍历结果为3、2、5、6、4、1。

4、层序遍历

层序遍历就是从上往下、从左至右逐层访问节点的过程。这个过程显然递归难以实现,这里可以借助队列来实现。具体方法如下:

第一步:将根节点入队列

第二步:如果队列不为空就访问队头元素

第三步:如果队头元素有孩子节点,就将孩子节点入队列

第四步:对头元素出队列

第五步:重复第二步到第四步直至队列为空

代码实现:

void BinaryTreeLevelOrder(BTNode* root) {
	if (root == NULL) {
		return;
	}
	Queue q;
	QueueInit(&q);
	//1、根节点入队列
	QueuePush(&q, root);
	while (!QueueEmpty(&q)) {
		BTNode* frontroot = QueueFront(&q);
		//2、判断队列不为空就访问队头元素
		printf("%d ", frontroot->_data);
		//3、如果队头节点有孩子,就将孩子入队列
		if (frontroot->_left != NULL) {
			QueuePush(&q, frontroot->_left);
		}
		if (frontroot->_right != NULL) {
			QueuePush(&q, frontroot->_right);
		}
		//3、队头节点出队列
		QueuePop(&q);
	}
	QueueDestroy(&q);
}

二、二叉树的创建(前序遍历)

在二叉树的创建过程中,为了能让每个节点确认是否有左右孩子,我们得对它进行扩展。扩展二叉树就可以做到一个遍历序列确定一颗二叉树。 如下图这样:

 建立二叉树的过程,也使用了递归的原理。只不过在原来打印节点的地方改成了生成节点。这里还有一些细节要注意,放在了注释中。

代码:

//形参为前序遍历的数组array,二叉树的节点数size,数组索引index(这里得是指针,因为
//在递归得过程中值得带出去),扩展二叉树用的数invalid
BTNode* BinaryTreeCreate(BTDataType array[],int size,int* index, BTDataType invalid) {
	BTNode* root = NULL;
	if (*index < size && array[*index] != invalid) {
		root = BuyNode(array[*index]);
		//注意索引的变换
		(*index)++;
		root->_left = BinaryTreeCreate(array, size, index, invalid);
		(*index)++;
		root->_right = BinaryTreeCreate(array, size, index, invalid);
	}
	return root;
}

三、求节点个数(注意递归思想的建立)

节点数 = 根节点 + 左子树的节点数 + 右子树的节点数

这里的出口是根节点为空。

int BinaryTreeSize(BTNode* root) {
	if (root == NULL) {
		return 0;
	}
	return 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
}

四、求叶子节点个数(注意递归思想的建立)

叶子节点数 = 左子树叶子节点个数 + 右子树叶子节点个数

这里的出口是根节点为叶子节点。

int BinaryTreeLeafSize(BTNode* root) {
	if (root == NULL) {
		return 0;
	}
	if (root->_left == NULL && root->_right == NULL) {
		return 1;
	}
	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

五、求第k层节点个数(注意递归思想的建立)

第k层节点个数 = 左子树第k-1层节点的个数 + 右子树第k-1层的个数

这里的出口为层数为1。

int BinaryTreeLevelKSize(BTNode* root, int k) {
	if (root == NULL) {
		return 0;
	}
	if (k == 1) {
		return 1;
	}
	return BinaryTreeLevelKSize(root->_left, k - 1)
		+ BinaryTreeLevelKSize(root->_right, k - 1);
}

六、判断是否为完全二叉树

判断方法为层序遍历二叉树,不同的是不管队头节点的孩子节点是否为空,都让它入队列。当队头元素为空指针时跳出循环,检测此时队列里是否还有二叉树的节点。如果没有,则是完全二叉树。

int BinaryTreeComplete(BTNode* root) {
	if (root == NULL) {
		return 1;
	}
	//层序遍历二叉树
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q)) {
		BTNode* frontroot = QueueFront(&q);
		if (frontroot == NULL) {
			//遇到空指针停止
			break;
		}
		QueuePush(&q, frontroot->_left);
		QueuePush(&q, frontroot->_right);
		QueuePop(&q);
	}
	//检查队列中除了空指针是否还有节点
	while (!QueueEmpty(&q)) {
		if (QueueFront(&q) != NULL) {
			return 0;
		}
		QueuePop(&q);
	}
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值