【数据结构地图】二叉树操作

二叉树是一种节点度<=2的树,即每个节点(根节点除外)最多只有两个子节点。满二叉树是每一层节点都达到最多的树,完全二叉树是遵循层序遍历法创建出的树,一层一层序号由小到大排列

 二叉树的节点结构体和一些操作的函数定义

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
struct BtNode {
	int data;
	BtNode* left;
	BtNode* right;
};
//函数声明
BtNode* preCreateBiTree();
void preOrderTraversal();
void inOrderTraversal();
void postOrderTraversal();
void preOrderTraversal_stack();
void inOrderTraversal_stack();
void postOrderTraversal_stack();
void levelOrderTraversal();

preOrderTraversal——先序遍历函数

  1. 判断根节点是否为空(是的话进2,不是的话函数直接返回)
  2.  访问根节点的数据
  3. 先序遍历左节点
  4. 先序遍历右节点
void preOrderTraversal(BtNode*root) {//先序遍历
	if (root == NULL) {
		return;
	}
	cout << root->data << ' ';
	preOrderTraversal(root->left);
	preOrderTraversal(root->right);
}

inOrderTraversal——中序遍历函数

  1. 判断根节点是否为空(是的话进2,不是的话函数直接返回)
  2.  先序遍历左节点
  3. 访问根节点的数据
  4. 先序遍历右节点
void inOrderTraversal(BtNode* root) {//中序遍历
	if (root == NULL) {
		return;
	}
	inOrderTraversal(root->left);
	cout << root->data << ' ';
	inOrderTraversal(root->right);
}

 postOrderTraversal——后序遍历函数

  1. 判断根节点是否为空(是的话进2,不是的话函数直接返回)
  2.  先序遍历左节点
  3. 先序遍历右节点
  4. 访问根节点的数据
void postOrderTraversal(BtNode* root) {//后续遍历
	if (root == NULL) {
		return;
	}
	postOrderTraversal(root->left);
	postOrderTraversal(root->right);
	cout << root->data << ' ';
}

 preOrderTraversal_stack——非递归先序遍历

  1. 先判定根节点是否为空(不为空进入2,为空函数返回)
  2. 将根节点压入栈
  3. 进入循环,循环条件为:栈不为空
  4. 临时指针p指向栈首元素
  5. 访问栈首元素值
  6. 弹栈一次
  7. 若之前栈首节点左指针不为空,左指针入栈
  8. 若之前栈首节点右指针不为空,右指针入栈
void preOrderTraversal_stack(BtNode*root) {
	if (NULL == root)return;
	stack<BtNode*>s;
	s.push(root);
	BtNode *p = NULL;
	while (!s.empty()) {
		p = s.top();
		cout << p->data << " ";
		s.pop();
		if (p->right != NULL)s.push(p->right);
		if (p->left != NULL)s.push(p->left);
	}
	cout << endl;
}

 inOrderTraversal_stack——非递归中序遍历

  1. 先判定根节点是否为空(不为空进入2,为空函数返回)
  2. 临时指针c指向根节点
  3. 临时指针p置空
  4. 进入循环,循环条件为:栈非空或者临时指针c非空
  5. (1)将根节点入栈
  6. (2)临时指针c指向根节点的左子节点
  7. 进入判定,条件为:栈为空,栈空则返回,不空则进8
  8. 将栈顶节点让临时指针c指向
  9. 访问栈顶节点
  10. 将c拷贝给p
  11. 弹栈一次
  12. 临时指针c指向右子节点
void inOrderTraversal_stack(BtNode*root) {
	if (NULL == root)
		return;
	stack<BtNode*>s;
	BtNode *c = root;
	BtNode *p = NULL;
	while (!s.empty() || c) {
		while (c && c != p) {
			s.push(c);
			c = c->left;
		}
		if (s.empty())
			return;
		c = s.top();
		cout << c->data << " ";
		p = c;
		s.pop();
		c = c->right;
	}
	cout << endl;
}

postOrderTraversal_stack——非递归后序遍历

 

void postOrderTraversal_stack(BtNode*root) {
	if (NULL == root)return;
	stack<BtNode*> s;
	s.push(root);
	BtNode *c = root->left;
	BtNode *p = NULL;
	while (!s.empty()) {
		while (c && c != p) {
			s.push(c);
			c = c->left;
		}
		if (s.empty())
			return;
		c = s.top();
		if (c->right && c->right != p) {
			c = c->right;
		}
		else {
			cout << c->data << " ";
			p = c;
			s.pop();
		}
	}
	cout << endl;
}

levelOrderTraversal——层序遍历函数

  1.  先判定根节点是否为空(不为空进2,为空函数返回)
  2. 临时指针p指向根节点指向的对象
  3. 将临时节点p入队
  4. 进入循环,条件为:队列不为空
  5. (1)临时指针current指向队列中首指针指向的对象实例
  6. (2)访问current指向的对象实例的数据
  7. (3)将队列元素弹出
  8. (4)current指针指向的对象实例中左指针若不为空,则将左指针入队
  9. (5)current指针指向的对象实例中右指针若不为空,则将右指针入队
void levelOrderTraversal(BtNode* root) {//层序遍历
	if (root == NULL) {
		cout << "树为空,无数据" << endl;
		return;
	}
	queue<BtNode*>Q;
	BtNode* p = root;//临时指针p指向根节点
	if (p != NULL) Q.push(p);//指针p入队
	while (!Q.empty()) {
		BtNode* current = Q.front();//队首元素为指针p,指针current也指向了根节点
		cout << current->data << " ";
		Q.pop();//访问完即出队
		if (current->left != NULL) Q.push(current->left);//左节点不为空则将左节点入队
		if (current->right != NULL) Q.push(current->right);//右节点同理
	}
}

 preCreateBiTree——先序创建函数

  1.  递归创建二叉树,递归退出条件为:输入-1
  2. 开辟空间后,将value的值赋给节点
  3. 当前节点左指针进入新先序遍历函数
  4. 当前节点右指针进入后先序遍历函数
BtNode* preCreateBiTree() {//先序创建二叉树
	int value;
	cin >> value;
	BtNode* p;
	if (value == -1) {//退出递归条件,输入-1则退出
		return NULL;//返回空指针
	}
	else{
		p = new BtNode();
		p->data = value;//赋值

		cout << "请输入左子树:" << endl;
		p->left = preCreateBiTree();
		cout << "请输入右子树:" << endl;
		p->right = preCreateBiTree();
		return p;//返回根节点
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值