



************************************

满二叉树是叶子一个也不少的树,而完全二叉树虽然前n-1层是满的,但最底层却允许在右边缺少连续若干个结点。满二叉树是完全二叉树的一个特例。
************************************
C++代码实现
#include<iostream>
#include<queue>
using namespace std;
#define OVERFLOW -2
#define OK 1
#define NULL 0
#define ERROR -1
#define MAXSIZE 100
typedef int Status;
typedef char TelemType;
/*------------------二叉树顺序存储----------------*/
/*
适于存满二叉树和完全二叉树
*/
// typedef TelemType SqBiTree[MAXSIZE];
// SqBiTree bt; // 包含100存放TelemType类型数据的数组
/*-----------------二叉树链式存储------------------*/
/*
二叉链表
*/
typedef struct BiTNode {
TelemType data; // 结点数据域
struct BiTNode* lchild, * rchild; // 左右子树指针
int flag; // 后序遍历标志位
}BiTNode, * BiTree;
typedef BiTree SElemType;
typedef struct {
BiTNode* link;
int tag; // 后序遍历标志位
}BElemType;
// 顺序栈结构体
typedef struct {
SElemType* base;
SElemType* top;
int stacksize;
}SqStack;
// 顺序栈初始化
Status InitStack(SqStack& S) {
S.base = new SElemType[MAXSIZE];
if (!S.base) return OVERFLOW;
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}
// 判断顺序栈是否为空
bool StackEmpty(SqStack S) {
if (S.top == S.base) return true;
else return false;
}
// 判断是否为满栈
bool StackFull(SqStack S) {
if (S.top - S.base >= S.stacksize)
return true;
else return false;
}
// 入栈
Status Push(SqStack& S, BiTree e) {
if (StackFull(S)) // 满栈
return ERROR;
*S.top++ = e;
// *S.top = e;
// S.top ++;
return OK;
}
// 出栈
Status Pop(SqStack& S, BiTree& e) {
if (StackEmpty(S)) // 栈空
return ERROR;
e = *--S.top;
// S.top --;
// e = *S.top;
return OK;
}
/*
# 遍历规则
- 若二叉树为空树,则空操作
- DLR-先序遍历,先根再左再右
- LDR-中序遍历,先左再根再右
- LRD-后序遍历,先左再右再根
*/
/*--------先序(根)遍历---------*/
// 递归算法
/*
若二叉树为空,则空操作
否则:
访问根结点 (D)
中序遍历左子树 (L)
中序遍历右子树 (R)
*/
void PreOrder(BiTree T) {
if (T) {
cout << T->data;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
// 非递归算法
void PreOrder_1(BiTree T) {
SqStack S;
InitStack(S);
BiTree p = T;
while (p || !StackEmpty(S)) {
// p非空且栈非空
if (p) {
/*
输出元素
保存入栈
p = p->lchild
*/
cout << p->data;
Push(S, p);
p = p->lchild;
}
else {
/*
出栈到p
p = p->rchild
*/
Pop(S, p);
p = p->rchild;
}
}
}
/*--------中序(根)遍历---------*/
// 递归算法
/*
若二叉树为空,则空操作
否则:
中序遍历左子树 (L)
访问根结点 (D)
中序遍历右子树 (R)
*/
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
cout << T->data;
InOrder(T->rchild);
}
}
// 非递归算法
void InOrder_1(BiTree T) {
BiTree p = T;
SqStack S;
InitStack(S);
while (p || !StackEmpty(S)) {
if (p) {
/*
保存--入栈
p = p->lchild
*/
Push(S, p);
p = p->lchild;
}
else {
/*
出栈到p
输出p->data
p = p->rchild
*/
Pop(S, p);
cout << p->data;
p = p->rchild;
}
}
}
/*
/*--------后序(根)遍历---------*/
// 递归算法
/*
若二叉树为空,则空操作
否则:
中序遍历左子树 (L)
中序遍历右子树 (R)
访问根结点 (D)
*/
void PostOrder(BiTree T) {
if (T) {
PostOrder(T->lchild);
PostOrder(T->rchild);
cout << T->data;
}
}
// 非递归算法
void PostOrder_1(BiTree T) {
/*
此函数应将数据类型改为"结点+标志位",即上面代码中BElemType类型
但由于修改类型后,需重新改写栈相关函数,故将标志位作为结构体BiTNode参数
*/
BiTree p = T;
SqStack S;
// BElemType w;
InitStack(S);
while (p || !StackEmpty(S)) {
if (p) {
/*
保存--入栈 flag = 1(结构体 p,flag)
p = p->lchild
*/
// w.link = p;
// Push(S,w);
Push(S, p);
p->flag = 1;
// w.tag = 1;
p = p->lchild;
}
else {
/*
出栈到p
switch(flag){
case '1':
入栈 flag = 2
p = p->rchild
case '2'
输出 p->data
p = NULL
}
保存--入栈
p = p->rchild;
*/
// Pop(S, w);
Pop(S, p);
// p = w.link;
switch (p->flag) {
case 1:
p->flag = 2;
// w.tag = 2;
Push(S, p);
p = p->rchild;
break;
case 2:
cout << p->data;
// 强制置空
p = NULL;
break;
}
}
}
}
// 求二叉树叶子结点的个数
int CountLeaf(BiTree T) {
// 先序遍历
// 此处必须为static类型,递归会调用自身,只赋一次值
static int count = 0;
if (T) {
if (!T->lchild && !T->rchild)
count++;
CountLeaf(T->lchild);
CountLeaf(T->rchild);
}
return count;
}
// 求二叉树深度
/*
1. 求左二叉树深度
2. 求右二叉树深度
3. 取最大值加1
*/
int Depth(BiTree T) {
// 后序遍历
int dl, dr, d;
if (!T)
d = 0;
else {
dl = Depth(T->lchild);
dr = Depth(T->rchild);
d = 1 + (dl > dr ? dl : dr);
}
return d;
}
// 复制二叉树
BiTree Copy(BiTree T) {
BiTree t, newl, newr;
if (!T) {
t = NULL;
return t;
}
else {
if (!T->lchild)
newl = NULL;
else
newl = Copy(T->lchild);
if (!T->rchild)
newr = NULL;
else
newr = Copy(T->rchild);
t = new BiTNode;
t->data = T->data;
t->lchild = newl;
t->rchild = newr;
}
return t;
}
// 先序创建二叉树
Status CreateBiTree(BiTree& T) {
char ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
if (!(T = new BiTNode)) exit(OVERFLOW);
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
int main() {
// 测试
BiTree T, t;
int n;
CreateBiTree(T);
// 递归遍历
cout << "先序遍历为:" << endl;
PreOrder(T);
cout << endl << "中序遍历为:" << endl;
InOrder(T);
cout << endl << "后序遍历为: " << endl;
PostOrder(T);
cout << endl;
// 叶子结点个数测试
cout << "叶子结点个数为: " << CountLeaf(T) << endl;
// 求树深度测试
cout << "树的深度为:" << Depth(T) << endl;
// 复制测试
t = Copy(T);
cout << "t 的先序遍历为: " << endl;
PreOrder(t);
cout << endl;
/*
// 非递归遍历
cout << "先序遍历为:" << endl;
PreOrder_1(T);
cout << endl;
cout << "中序遍历为:" << endl;
InOrder_1(T);
cout << endl;
cout << "后序遍历为:" << endl;
PostOrder_1(T);
cout << endl;
*/
return 0;
}ab##c##先序遍历为:abc中序遍历为:bac后序遍历为:bca叶子结点个数为: 2树的深度为:2t 的先序遍历为:abc************************************
python代码实现
'''案例ly01.py'''
class Node(object):
'''节点类'''
def __init__(self, elem=-1, lchild=None, rchild=None):
self.elem = elem;
self.lchild = lchild
self.rchild = rchild
class Tree(object):
'''树类'''
def __init__(self, root=None):
self.root = root
def add(self, elem):
'''为树添加节点'''
node = Node(elem)
# 如果树是空的,则对根节点赋值
if self.root == None:
self.root = node
else:
queue = []
queue.append(self.root)
# 对已有的节点进行层次遍历
while queue:
# 弹出队列的第一个元素
cur = queue.pop(0)
if cur.lchild == None:
cur.lchild = node
return
elif cur.rchild == None:
cur.rchild = node
return
else:
# 如果左右子树都不为空,加入队列继续判断
queue.append(cur.lchild)
queue.append(cur.rchild)
def preorder(self, root):
'''递归实现先序遍历'''
if root == None:
return
print(root.elem)
self.preorder(root.lchild)
self.preorder(root.rchild)
def inorder(self, root):
'''递归实现中序遍历'''
if root == None:
return
self.inorder(root.lchild)
print(root.elem)
self.inorder(root.rchild)
def postorder(self, root):
'''递归实现后序遍历'''
if root == None:
return
self.postorder(root.lchild)
self.postorder(root.rchild)
print(root.elem)
def breadth_travel(self, root):
'''利用队列实现树的层次遍历'''
if root == None:
return
queue = []
queue.append(root)
while queue:
node = queue.pop(0)
print(node.elem)
if node.lchild != None:
queue.append(node.lchild)
if node.rchild != None:
queue.append(node.rchild)
if __name__ == '__main__':
t = Tree()
for i in range(10):
t.add(i)
t.preorder(t.root)
print('*' * 20)
t.inorder(t.root)
print('*' * 20)
t.postorder(t.root)
print('*' * 20)
t.breadth_travel(t.root)0137849256********************7381940526********************7839415620********************0123456789[Finished in 0.1s]/*---------二叉树的二叉线索存储表示---------*/
typedef int ElemType;
typedef enum PointerTag {Link, Thread}; // Link==0:指针,Thread==1:线索
typedef struct BiThrNode {
ElemType data; // 数据域
struct BiThrNode* lchild, * rchild; // 左右孩子指针
PointerTag LTag, Rtag; // 左右标志
}BiThrNode, * BiThrTree;/*----------以结点p为根的子树中序线索化---------*/
void InThreading(BiThrTree p, BiThrNode *&pre) {
if (p) {
InThreading(p->lchild, pre); // 递归线索化左子树
if (!p->lchild) {
p->LTag = Thread; // 前驱线索化
p->lchild = pre; // p的左孩子指针指向pre(前驱)
}
if (!pre->rchild) {
// 前驱无右孩子
pre->RTag = Thread; // 后继线索
pre->rchild = p; // 前驱右孩子指向后继
}
pre = p;
InThreading(p->rchild, pre); // 递归线索化右子树
}
}树转换成的二叉树其右子树一定为空
树的先序遍历与二叉树先序遍历相同
树的后序遍历相当于对应二叉树的中序遍历
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。