####一、树的表示方法:
树的基础知识请参考以下博客:
http://blog.csdn.net/dai_wen/article/details/78929433
1,图形表示法:
2,广义表表示法:
3,孩子兄弟表示法
在日常生活中,常常听到长兄如父的说法,这里的孩子兄弟表示法是否也如此呢?
对于如下所示的树:(一棵普通的树)
将其第一个孩子结点保留,其余孩子结点与其原有的双亲结点断开,并将其连接到第一个孩子结点上,则有:
整理得出:
其实,采用这种方式表示,可以将一颗普通的树转为一颗二叉树;那么,为什么要将数转为二叉树呢?
这就像计算机实现进制之间的转换一样,先将最简单,最基础的二进制运算实现,再将其它进制转为二进制,最后实现,那么,数直接存储不好实现,现实现二叉树,再在二叉树的基础上来操作,就显得容易的多;
####二,二叉树的存储方式:
首先:对于一颗树:可以采取顺序的存储方式,也可采用链式方式进行存储;
1,顺序存储:
规定:从上到下,从左至右依次保存树中的结点
(A,B,D,C,E,F)
缺陷:若给定一个序列,无法知道一个结点是某节点的左,右孩子还是后继,
//如上述序列,C到底是B的右孩子,还是D的左孩子,还是其他,无法确认,也就是说,如果已知存储序列,很难将其复原成一颗树;
解决方案: 为了能找到某一结点的上下左右关系,也必须仿照完全二叉树的方式来存储,遇到空树,在顺序表中应该将该位置空出来。
(如下将空树用#表示)
缺陷:采用这种方式,内存空间浪费太多;
2,链式存储:
由一个前驱指针和N个后继指针构成,那么后继指针到底有多少个?是给成指定等长还是不定长?
(1)两个指针域:
//二叉树结点类型定义
typedef struct node* tree_pointer;
typedef struct node
{
int data;
tree_pointer lchild,rchild;
}node;
如下所示:
(2)三个指针域:
//三叉链表
typedef struct TirTNode
{
int data;
struct TriTNode * lchild,*rchild;//指向孩子结点
struct TriTNode *parent;//指向双亲结点
}TriTNode,*TriTree;
(3),双亲表示法:
//双亲链表
#define MAX_TREE_SIZE 100
typedef struct BPTNode
{
int data;
int *parent;//指向双亲结点
char LRTag;//左右孩子标记
}BPTNode;
如下所示:
总结来说:树的存储方式有孩子表示法,双亲表示法,孩子兄弟法,孩子双亲法,我们最常用的是孩子双亲法。
二叉树的具体性质,请参考
http://blog.csdn.net/dai_wen/article/details/78929433