二叉树是一种节点度<=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——先序遍历函数
- 判断根节点是否为空(是的话进2,不是的话函数直接返回)
- 访问根节点的数据
- 先序遍历左节点
- 先序遍历右节点
void preOrderTraversal(BtNode*root) {//先序遍历
if (root == NULL) {
return;
}
cout << root->data << ' ';
preOrderTraversal(root->left);
preOrderTraversal(root->right);
}
inOrderTraversal——中序遍历函数
- 判断根节点是否为空(是的话进2,不是的话函数直接返回)
- 先序遍历左节点
- 访问根节点的数据
- 先序遍历右节点
void inOrderTraversal(BtNode* root) {//中序遍历
if (root == NULL) {
return;
}
inOrderTraversal(root->left);
cout << root->data << ' ';
inOrderTraversal(root->right);
}
postOrderTraversal——后序遍历函数
- 判断根节点是否为空(是的话进2,不是的话函数直接返回)
- 先序遍历左节点
- 先序遍历右节点
- 访问根节点的数据
void postOrderTraversal(BtNode* root) {//后续遍历
if (root == NULL) {
return;
}
postOrderTraversal(root->left);
postOrderTraversal(root->right);
cout << root->data << ' ';
}
preOrderTraversal_stack——非递归先序遍历
- 先判定根节点是否为空(不为空进入2,为空函数返回)
- 将根节点压入栈
- 进入循环,循环条件为:栈不为空
- 临时指针p指向栈首元素
- 访问栈首元素值
- 弹栈一次
- 若之前栈首节点左指针不为空,左指针入栈
- 若之前栈首节点右指针不为空,右指针入栈
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——非递归中序遍历
- 先判定根节点是否为空(不为空进入2,为空函数返回)
- 临时指针c指向根节点
- 临时指针p置空
- 进入循环,循环条件为:栈非空或者临时指针c非空
- (1)将根节点入栈
- (2)临时指针c指向根节点的左子节点
- 进入判定,条件为:栈为空,栈空则返回,不空则进8
- 将栈顶节点让临时指针c指向
- 访问栈顶节点
- 将c拷贝给p
- 弹栈一次
- 临时指针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——层序遍历函数
- 先判定根节点是否为空(不为空进2,为空函数返回)
- 临时指针p指向根节点指向的对象
- 将临时节点p入队
- 进入循环,条件为:队列不为空
- (1)临时指针current指向队列中首指针指向的对象实例
- (2)访问current指向的对象实例的数据
- (3)将队列元素弹出
- (4)current指针指向的对象实例中左指针若不为空,则将左指针入队
- (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
- 开辟空间后,将value的值赋给节点
- 当前节点左指针进入新先序遍历函数
- 当前节点右指针进入后先序遍历函数
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;//返回根节点
}
}