树和二叉树
树:是由n个结点构成的有限集合T。若n=0称为空树
基本术语
结点:数据元素+若干指向子树的分支
结点的度:分支的个数
树的度:树中所有结点的度的最大值
叶子结点:度为零的结点
分支结点:度大于零的结点
路径:从根到该结点所经分支和结点构成
孩子结点、双亲结点、兄弟结点、祖先结点、子孙结点
有序树:把子结点按从左到右的次序顺序编号,结点的位置固定,不能互换,即使其他结点删除,它的编号也不变
二叉树
定义
二叉树是n个结点的有限集合,该集合为空,或者由一个根结点及两棵互不相交的左、右子树构成,而且其左右子树均为二叉树。
度为2的有序树不是二叉树
满二叉树:如果一棵二叉树中任意一层的结点个数都到达了最大值,则此二叉树称为满二叉树。一棵高度为k的满二叉树具有2^k-1个结点
完全二叉树:对于深度为k,有n个结点的完全二叉树,其中每个结点都与深度为k的满二叉树中编号从1到n的绩点一一对应。
特征:
- 叶子结点只能出现在最后一层和倒数第二层
- 任一结点,如果它左分支子孙的最大层次为l,那么它右分支的最大层次为l或l-1。
性质
- 一棵非空二叉树的第i层上最多有2^(i-1)个结点(i>=1)
- 一棵高度为k的二叉树,最多有2^k - 1个结点
- 任何一棵二叉树中,若叶子数为n0,度为2的结点数为n2,则n0=n2 + 1
- 具有n个结点的完全二叉树的高度k = log2(n+1)向上取整
二叉树的存储结构
1 顺序存储
#defnie MAX_TREE_SIZE 100
typedef TElemTypt SqBiTree[MAX_TREE_SIZW];
SqBiree bt;
//将二叉树按有序树编号,将结点存储到对应编号的位置
- 链式存储
- 二叉链表
typedef struct BiTNode{
TElemType data;//结点存储的值
struct BiTNode *lchild,*rchlid;//结点的左右孩子指针
}BiTNode,*BiTree;
- 三叉链表
typedef struct BiTNode
{
struct TElemType data;
struct BiTNode* lchild, * rchild, * parent;
}TriTNode,*TriTree;
- 双亲链表
typedef struct BPTNode{
TElemType data;
int *parent;
char LRTag;
}BPTNode;
typedef struct BPTree{
BPTNode nodes[MAX_TREE_SIZE];
int num_node; //结点数目
int root; //根结点的位置
}BPTree;
二叉树的遍历和建立
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//二叉树的存储结构,一个数据域,2个指针域
typedef char ElemType;
typedef struct BiTNode
{
char data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
//二叉树的前序遍历方式创建
void PreCreateBiTree(BiTree& T)
{
ElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = new BiTNode;
if (!T)
exit(-1);
T->data = ch;
PreCreateBiTree(T->lchild);
PreCreateBiTree(T->rchild);
}
}
BiTree CreateBTree(ElemType a[], ElemType b[], int n) //对应例2.8的算法
//由先序序列a[0..n-1]和中序序列b[0..n-1]建立二叉链
{
int k;
if (n <= 0) return NULL;
ElemType root = a[0]; //根结点值
BiTree bt = (BiTNode*)malloc(sizeof(BiTNode));
bt->data = root;
for (k = 0; k < n; k++) //在b中查找b[k]=root的根结点
if (b[k] == root)
break;
bt->lchild = CreateBTree(a + 1, b, k); //递归创建左子树
bt->rchild = CreateBTree(a + k + 1, b + k + 1, n - k - 1); //递归创建右子树
return bt;
}
void PreOrderTraverse(BiTree T)//二叉树的先序遍历
{
if (T == NULL)
return;
cout << T->data << "\t";
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
void InOrderTraverse(BiTree T)//二叉树的中序遍历
{
if (T == NULL)
return;
InOrderTraverse(T->lchild);
cout << T->data << "\t";
InOrderTraverse(T->rchild);
}
void PostOrderTraverse(BiTree T)//后序遍历
{
if (T == NULL)
return;
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data << "\t";
}
int main() {
BiTree bt;
PreCreateBiTree(bt);
PreOrderTraverse(bt);
return 0;
}