完全二叉树的性质
完全二叉树:在满二叉树中,从最后一个结点开始,连续去掉任意个结点得到的二叉树。
性质1:对一棵具有 n 个结点的完全二叉树中从 1 开始按层序编号,对于任意的序号为 i(1≤i≤n)的结点(简称结点 i),有:
(1)如果 i>1,则结点 i 的双亲结点的序号为 i/2,否则结点 i 无双亲结点
(2)如果 2i≤n,则结点 i 的左孩子的序号为 2i,否则结点 i 无左孩子
(3)如果 2i+1≤n,则结点 i 的右孩子的序号为2i+1,否则结点 i 无右孩子
通过性质1,我们可以得到寻找根节点的左子树和右子树的方法,进而创建递归算法。
完全二叉树的存储
采用顺序结构即按层序编号的顺序存储所有结点,例如采用一维数组data[MaxSize]存储上图的完全二叉树,用data[0]来存储结点数,data[1]即为根节点。
显然,按图数组顺序存储方式,将下标为0的单元存放结点数,那么各结点所在的下标与层序编号一致。在二叉链表的递归中序遍历算法的基础上,用结点下标代替结点的地址,即可实现顺序存储的递归中序遍历
代码如下:
void AbsBiTree::seqInOrder(int i) {
if (i == 0) {//递归的结束条件
return;
}
else {
if (2 * i <= data[0]) {
//遍历左子树
seqInOrder(2 * i);
}
else {
seqInOrder(0);
}
//访问根节点
cout << data[i] << ' ';
if (2 * i + 1 <= data[0]) {
//遍历右子树
seqInOrder(2 * i + 1);
}
else {
seqInOrder(0);
}
}
}
完整代码:
包含三种遍历
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
const int MaxSize = 100;
class AbsBiTree
{
public:
AbsBiTree() {
}
AbsBiTree(char a[], int n);
~AbsBiTree() {
}
void seqInOrder() {
cout << "完全二叉树中序遍历为:";
seqInOrder(1);
cout << endl;
}
void seqPreOrder() {
cout << "完全二叉树前序遍历为:";
seqPreOrder(1);
cout << endl;
}
void seqPostOrder() {
cout << "完全二叉树后序遍历为:";
seqPostOrder(1);
cout << endl;
}
void seqInOrder(int i);
void seqPreOrder(int i);
void seqPostOrder(int i);
private:
char data[MaxSize];
};
//传入按层序排序的完全二叉树
AbsBiTree::AbsBiTree(char a[],int n)
{
if (n + 1 > MaxSize) {
cout << "二叉树超载" << endl;
exit(0);
}
data[0] = n;
for (int i = 0; i < n; i++) {
data[i+1] = a[i];
}
}
void AbsBiTree::seqInOrder(int i) {
if (i == 0) {//递归的结束条件
return;
}
else {
if (2 * i <= data[0]) {
//遍历左子树
seqInOrder(2 * i);
}
else {
seqInOrder(0);
}
//访问根节点
cout << data[i] << ' ';
if (2 * i + 1 <= data[0]) {
//遍历右子树
seqInOrder(2 * i + 1);
}
else {
seqInOrder(0);
}
}
}
void AbsBiTree::seqPreOrder(int i) {
if (i == 0) {
return;
}
else {
cout << data[i] << ' ';
if (2 * i <= data[0]) {
seqPreOrder(2 * i);
}
else {
seqPreOrder(0);
}
if (2 * i + 1 <= data[0]) {
seqPreOrder(2 * i + 1);
}
else {
seqPreOrder(0);
}
}
}
void AbsBiTree::seqPostOrder(int i) {
if (i == 0) {
return;
}
else {
if (2 * i <= data[0]) {
seqPostOrder(2 * i);
}
else {
seqPostOrder(0);
}
if (2 * i + 1 <= data[0]) {
seqPostOrder(2 * i + 1);
}
else {
seqPostOrder(0);
}
cout << data[i] << ' ';
}
}
void test();
void test() {
char a[] = { 'A','B','C','D','E','F','G','H','I','J' };
AbsBiTree bi(a, sizeof(a) / sizeof(char));
cout << sizeof(a) / sizeof(char) << endl;
bi.seqInOrder();
bi.seqPreOrder();
bi.seqPostOrder();
}
int main() {
test();
}