数据结构:树
一、二叉树的结构特性
二、二叉树的各种存储结构的特点及适用范围
1.顺序存储结构
该方法是把二叉树的所有结点按照一定的线性次序存储到一片连续的存储单元中。结点在这个序列中的相互位置还能反映出结点之间的逻辑关系。
2、链式存储结构
三、二叉树的遍历
遍历二叉树,就是遵从某种次序,访问二叉树中的所有结点,使得每个结点仅被访问一次。
1.中序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
- 遍历左子树;
- 访问根结点;
- 遍历右子树。
2.先序遍历的递归算法定义: 若二叉树非空,则依次执行如下操作:
-
访问根结点;
-
遍历左子树;
-
遍历右子树。
3.后序遍历得递归算法定义: 若二叉树非空,则依次执行如下操作:
-
遍历左子树;
-
遍历右子树;
-
访问根结点。
四、线索二叉树
1.定义
n个结点的二叉链表中含有n+1个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前趋和后继结点的指针(这种附加的指针称为"线索")。
这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。
2.线索二叉树的表示
五、哈夫曼树及其应用
1.哈夫曼树
在权为wl,w2,…,wn的n个叶子所构成的所有二叉树中,带权路径长度最小(即代价最小)的二叉树称为最优二叉树或哈夫曼树。
2.编码和解码
-
数据压缩过程称为编码。即将文件中的每个字符均转换为一个惟一的二进制位串。
-
数据解压过程称为解码。即将二进制位串转换为对应的字符。
3.字符集编码的存储结构及其算法描述
1 ///Name:Tree 2 ///Author:JA 3 ///Date:2015-3-10 4 5 6 7 ///二叉树的存储结构 8 ///二叉树的顺序存储表示 9 #define MSX_TREE_SIZE 100 //二叉树的最大结点数 10 typedef TElemType SqBiTree[MSX_TREE_SIZE] //0号单元存储根结点 11 SqBiTree bt; 12 13 ///二叉树的链表存储表示 14 typedef struct BiTNode{ 15 TElemType data; 16 struct BiTNode *lchild, *rchild; //左右孩子指针 17 }BiTNode,*BiTree; 18 19 20 ///中序遍历算法实现 21 void InOrder(BiTree T) 22 { 23 if (T){ 24 InOrder(T->lchild); 25 printf("%c", T->data); //访问结点 26 InOrder(T->rchild); 27 } 28 }//InOrder 29 30 ///哈弗曼树和哈弗曼编码的存储表示 31 typedef struct { 32 char ch; //存储字符 33 char bits[n + 1]; //存放编码位串 34 }CodeNode; 35 36 typedef CodeNode HuffmanCode[n]; 37 void CharSetHuffmanEncoding(HuffmanTree T,HuffmanCode H) 38 {//根据哈夫曼树T求哈夫曼编码表H 39 int c,p,i;//c和p分别指示T中孩子和双亲的位置 40 char cd[n + 1]; //临时存放编码 41 int start; //指示编码在cd中的起始位置 42 cd[n] = '\0'; //编码结束符 43 for (i = 0,i<n,i++){ //依次求叶子T[i]的编码 44 H[i].ch = getchar();//读入叶子T[i]对应的字符 45 start = n; //编码起始位置的初值 46 c = i; //从叶子T[i]开始上溯 47 while ((p = T[c].parent) >= 0){//直至上溯到T[c]是树根为止 48 //若T[c]是T[p]的左孩子,则生成代码0;否则生成代码1 49 cd[--start] = (T[p).1child == C) ? '0':'1'; 50 c = p; //继续上溯 51 } 52 strcpy(H[i].bits,&cd[start]); //复制编码位串 53 }//endfor 54 }//CharSetHuffmanEncoding