第五章学习小结

一、本章内容小结

本章学习了树和二叉树。重点学习了二叉树的遍历算法还有哈夫曼树,二叉树的遍历算法的作用不单单是遍历,它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核心。

1.树:包括空树和非空树,包括三种存储结构:双亲表示法、孩子表示法、孩子兄弟表示法(应用较为普遍);还学习了森林和二叉树的转换。

树的基本术语包括结点、结点的度:分支的个数,树的度:树中所有结点的度的最大值,树的深度:数钟叶子结点所在的最大层次,叶子结点、分支结点、孩子结点、兄弟结点和祖先结点等。我觉得结点的度、树的度、树的深度比较容易混淆,而各类表示关系的结点可将树的图形结构看成一张遗传系谱图,各结点间的关系显得很直观。

2.二叉树----结点的度小于等于2,有5种不同形态,有5个性质,这些性质都可以通过数学计算推导出来;有两种特殊的二叉树:满二叉树(又称完美二叉树)、完全二叉树,我觉得可以用它们结点的度加以区分。

存储结构:顺序存储:适用于不需要修改的完全二叉树,而链式存储的适用范围较广,结构如下:

 1 //二叉链表
 2 typedef struct BiTNode
 3 {
 4     TElemType data;
 5     struct BiTNode *lchild, *rchild;      
 6 }BiTNode, *BiTree;
 7 
 8 //三叉链表
 9 typedef struct TriTNode
10 {
11     TElemType data;
12     struct TriTNode *lchid, *parent, *rchild;
13 }TriTNode, *TriTree;

先左后右的二叉树遍历算法:先(根)序遍历算法、中(根)序遍历算法、后(根)序遍历算法,其代码实现有两种:

递归算法:

 1 //先序遍历
 2 void PreOrderTraverse(BiTree T)
 3 {
 4     if(T)
 5     {
 6         cout<<T->data;
 7         PreOrderTraverse(T->lchild);
 8         PreOrderTraverse(T->rchild);
 9     }
10 }
11 
12 //中序遍历
13 void InOrderTraverse(BiTree T)
14 {
15     if(T)
16     {
17         InOrderTraverse(T->lchild);
18         cout<<T->data;
19         InOrderTraverse(T->rchild);
20     }
21 }
22 
23 //后序遍历
24 void PostOrderTraverse(BiTree T)
25 {
26     if(T)
27     {
28         PostOrderTraverse(T->lchild);
29         PostOrderTraverse(T->rchild);
30         cout<<T->data;
31     }
32 }

迭代算法:

 1 //先序遍历
 2 void PreOrderIteration(BiTree T)
 3 {
 4     stack<BiTree> s;
 5     BiTree p;
 6     if(T!=NULL)   s.push(T);
 7     while(!s.empty())
 8     {
 9         p=s.top();
10         s.pop();
11         cout<<p->data<<" ";
12         if(p->rchild!=NULL)  s.push(p->rchild);
13         if(p->lchild!=NULL)  s.push(p->lchild);
14     }
15 } 
16 
17 //中序遍历
18 void InOrderIteration(BiTree T)
19 {
20     stack<BiTree> s;
21     BiTree p=T;
22     while(p!=NULL || !s.empty())
23     {
24         while(p!=NULL)//一直走到左尽头 
25         {
26             s.push(p); //期间结点入栈 
27             p=p->lchild;
28         }
29         p=s.top();  //左已访问右未访问 
30         s.pop();
31         cout<<p-data<<" ";
32         p=p->rchild;  //准备遍历右子树 
33     }    
34 } 

个人觉得递归算法比迭代算法更易于理解,而且这两种算法的时间复杂度都为O(n),时间复杂度也都为O(n)。但迭代算法在一些方面也有优势,其运用了栈和队列的思想,而第五章pta的实践1的List Leave就运用了队列的思想。

二叉树遍历算法的应用举例:

 1 //先序建立二叉树
 2 void CreateBiTree(BiTree &T)
 3 {
 4     cin>>ch;
 5     if(ch=='#')   T=NULL;
 6     else
 7     {
 8         T=new BiTNode;
 9         T->data=ch;
10         CreateBiTree(T->lchild);
11         CreateBiTree(T->rchild);
12     }
13 }
14 
15 //先序复制二叉树
16 void Copy(BiTree T, BiTree &NewT)
17 {
18     if(T==NULL)
19     {
20         NewT=NULL;  return;
21     }
22     else
23     {
24         NewT=new BiTNode;
25         NewT->data=T->data;
26         Copy(T->lchild,NewT->lchild);
27         Copy(T->rchild,NewT->rchild);    
28     }
29 }
30 
31 //计算二叉树深度
32 int Depth(BiTree T)
33 {
34     if(T=NULL)  return 0;
35     else
36     {
37         DepthLeft=Depth(T->lchild);    
38         DepthRight=Depth(T->rchild);    
39         return(1+max(DepthLeft,DeptjRight));
40     } 
41 }
42  
43 //计算二叉树结点总数 
44 int NodeCount(BiTree T)
45 {
46     if(T=NULL)  return 0;
47     else
48     {
49         return     NodeCount(T->lchild)+NodeCount(T->rchild)+1;//每一个+1,代表每一个结点!!! 
50     } 
51 }

3.线索二叉树:保存了前驱和后继两个信息,利用了空链域

1 //二叉树的二叉线索存储定义
2 typedef struct BiThrNode
3 {
4     TElemType data;
5     struct BiThrNode *lchild, *rchild;
6     int LTag, RTag;
7 }BiThrNode, *BiThrTree; 

通过对标志域LTag和RTag存储数值的判断来决定lchild和rchild域的指向!

4.哈夫曼树:又称最优树,约定其左分支代表0,右分支代表1,便构造出了哈夫曼编码;哈夫曼树的构造也有一定的方法可循。

相关概念:路径、路径长度、树的路径长度、权、结点的带权路径长度、树的带权路径长度。

哈夫曼树的存储表示:

1 typedef struct
2 {
3     int weight;  //结点的权值 
4     int parent, lchild, rchild;  //结点的双亲、左孩子、右孩子的下标 
5 }HTNode, *HuffmanTree;   //动态分配数组存储哈夫曼树 

哈夫曼编码满足两个性质:

A.哈夫曼编码是前缀编码。

B.哈夫曼编码是最优前缀编码。

二、实践心得

在限时测试时,把层序遍历和先序遍历弄混了,后来也分清了二者的区别。在看过慕课的带你打代码后,能及时地复现出来,但过段时间又会有点模糊,需要定时地回顾一下。打实践1的树的同构时,顺带回顾了typedef struct和struct定义结构体的不同之处,也看了一些博客,https://blog.csdn.net/haiou0/article/details/6877718,这一篇就讲得很细!

posted on 2020-05-28 11:36  周淑霞  阅读(215)  评论(0编辑  收藏  举报