点击查看代码
//二叉树的静态实现(使用数组存储结点)
#include<cstdio>
#include<queue>
using namespace std;
#pragma warning(disable:4996)
const int maxn = 1000; //二叉树最多有1000个结点
struct node {
int data; //结点权值
int lchild; //左孩指针
int rchild; //右孩指针
}Node[maxn]; //结点数组,maxn为结点上限个数
int index = 0; //二叉树结点下标
//在二叉树中插入一个新结点,index为下标
int newNode(int v) {
Node[index].data = v; //结点权值为v
Node[index].lchild = -1; //使用-1或maxn表示空地址,因为数组下标范围是0~maxn-1
Node[index].rchild = -1;
return index++; //返回结点下标,然后再令index加一作为下一个结点下标
}
//二叉树查找权值为x的结点,并将它的权值修改为newdata
void search(int root, int x, int newdata) {
if (root == -1) { //用-1表示空结点地址NULL
return; //遇到空结点时结束递归
}
if (Node[root].data == x) { //找到权值为x的结点
Node[root].data = newdata; //将结点权值修改为newdata
}
search(Node[root].lchild, x, newdata); //进入左子树查找
search(Node[root].rchild, x, newdata); //进入右子树查找
}
//二叉树插入权值为x的结点,因为结点下标要修改,所以用引用型
void insert(int& root, int x) {
if (root == -1) { //遇到空结点时,在空结点位置插入新结点
root = newNode(x); //创建一个权值为x的新结点,将结点下标赋值给root
return;
}
if (根据二叉树性质判断,权值为x的结点插在左子树) {
insert(Node[root].lchild, x); //进入左子树查找插入位置
}
else {
insert(Node[root].rchild, x); //进入右子树查找插入位置
}
}
//二叉树的建立,函数返回根结点root的下标
int create(int data[], int n) {
int root = -1; //新建根结点,初始指向空地址-1
for (int i = 0; i < n; i++) {
insert(root, data[i]); //将data[0]~data[n-1]插入二叉树中
}
return root; //返回根结点下标
}
//先序遍历
void preorder(int root) {
if (root == -1) { //到达空结点,则结束递归返回上一层
return;
}
//访问根结点,执行相关操作,如输出根结点权值
printf("%d\n", Node[root].data);
preorder(Node[root].lchild); //递归进入左子树
preorder(Node[root].rchild); //递归进入右子树
}
//中序遍历
void inorder(int root) {
if (root == -1) { //到达空结点,则结束递归返回上一层
return;
}
inorder(Node[root].lchild); //递归进入左子树
//访问根结点,执行相关操作,如输出根结点权值
printf("%d\n", Node[root].data);
inorder(Node[root].rchild); //递归进入右子树
}
//后序遍历
void postorder(int root) {
if (root == -1) { //到达空结点,则结束递归返回上一层
return;
}
postorder(Node[root].lchild); //递归进入左子树
postorder(Node[root].rchild); //递归进入右子树
//访问根结点,执行相关操作,如输出根结点权值
printf("%d\n", Node[root].data);
}
//层序遍历
void layerorder(int root) {
queue<int> q; //定义队列q,存储结点在数组中的下标
q.push(root); //将根结点入队
while (!q.empty()) { //只要队列非空,就执行层序遍历
int now = q.front(); //取出队首元素,将结点下标存入now变量中
q.pop(); //队首元素取出后,要手动删除
//访问结点,执行相关操作,如输出结点权值
printf("%d\n", Node[now].data);
if (Node[now].lchild != -1) { //结点左孩非空,则将左孩结点下标存入队列q中
q.push(Node[now].lchild);
}
if (Node[now].rchild != -1) { //结点右孩非空,则将右孩结点下标存入队列q中
q.push(Node[now].rchild);
}
}
}