C++实现二叉树层序遍历、前中后序等

46 篇文章 6 订阅
24 篇文章 12 订阅


利用队列实现层序遍历

广度优先遍历

void LevelOrder(Node *root) {
	if (root == NULL) {
		printf("\n");
	}

	// 启动
	std::queue<Node *> q;
	q.push(root);

	while (!q.empty()) {
		Node *front = q.front();
		q.pop();

		printf("%c ", front->value);

		if (front->left != NULL) {
			q.push(front->left);
		}

		if (front->right != NULL) {
			q.push(front->right);
		}
	}
	printf("\n");
}

判断是否为完全二叉树

bool IsComplete(Node *root) {
	std::queue<Node *> q;
	q.push(root);

	while (true) {
		Node *front = q.front();
		q.pop();

		if (front == NULL) {
			break;
		}

		// 层序遍历,空结点也进队列
		q.push(front->left);
		q.push(front->right);
	}

	// 判定队列中剩余数据是否全是 NULL
	while (!q.empty()) {
		Node *front = q.front();
		q.pop();
		if (front != NULL) {
			return false;
		}
	}
	// 所有都是 NULL
	return true;
}

测试代码

void Test1() {
	char *inorder = "DBEAC";
	char *postorder = "DEBCA";
	int size = strlen(inorder);

	Node *root = buildTree2(inorder, postorder, size);

	LevelOrder(root);
	if (IsComplete(root)) {
		printf("是完全二叉树\n");
	}
	else {
		printf("不是完全二叉树\n");
	}
}

用栈实现前、中、后序(非递归方式)

栈实现前序

void PreOrderNoR(Node *root) {
	std::stack<Node *> s;
	Node *cur = root;

	while (cur != NULL || !s.empty()) {		//一开始栈为空,cur不为空
		while (cur != NULL) {
			printf("%c ", cur->value);
			s.push(cur);
			cur = cur->left;
		}
		Node *top = s.top(); s.pop();
		cur = top->right;
	}
}

测试代码

void Test2() {
	char *inorder = "DBEAC";
	char *postorder = "DEBCA";
	int size = strlen(inorder);

	Node *root = buildTree2(inorder, postorder, size);

	PreOrderNoR(root);
}

栈实现中序

void InOrderNoR(Node *root) {
	std::stack<Node *> s;
	Node *cur = root;

	while (cur != NULL || !s.empty()) {
		while (cur != NULL) {
			s.push(cur);	//第一次遇到结点
			cur = cur->left;
		}
		Node *top = s.top(); s.pop();
		printf("%c ", top->value);	//第二次遇到结点
		cur = top->right;
	}
}

栈实现后序

void PostOrderNoR(Node *root) {
	std::stack<Node *> s;
	Node *cur = root;
	Node *last = NULL;

	while (cur != NULL || !s.empty()) {
		while (cur != NULL) {
			// 第一次遇到
			s.push(cur);
			cur = cur->left;
		}

		Node *top = s.top();
		// 不知道是第二次遇到还是第三次遇到
		if (top->right == NULL) {	//右孩子为空,说明右子树也为空,不进行右子树的遍历【2、3次遇到】
			printf("%c ", top->value);	//打印,表示这个结点遍历完了,直接出栈
			s.pop();
			last = top;
		}
		else if (top->right == last) {	//【第三次遇到】
			printf("%c ", top->value);
			s.pop();
			last = top;
		}
		else {		//从左边过来的,右子树没有遍历过,【第二次遇到】
			cur = top->right;
		}
	}
}

注意,无论某一结点时,栈内存的数据总是:从根到该结点的路径

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

giturtle

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

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

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

打赏作者

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

抵扣说明:

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

余额充值