ImageVerifierCode 换一换
格式:DOCX , 页数:107 ,大小:725.40KB ,
资源ID:29384650      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/29384650.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(树的学习.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

树的学习.docx

1、树的学习树 和 二叉树 树形结构是非线性数据结构,其特点是数据元素只有一个前驱,但可以有零个或多个后继。 树,由结点和通向结点的分支组成,结点分层,除了第一层外,每个结点只有一个前驱,却可能有多个后继。 树是包含n(n=0)个结点的有限结合。 树的递归定义刻画了树的固有特性,即一颗非空树是由若干棵子树构成的,而子树又可由若干棵更小的子树构成。树的逻辑表示方法 1),二元组表示法 2),树形表示法 3),嵌套集合表示法 4),凹入表示法 5),广义表表示法树的基本术语: 1),结点;2),结点的度;3),树的度;4),叶子结点;5),分支结点;6),双亲和孩子;7),兄弟和堂兄弟;8),路径;9

2、),祖先和子孙;10),结点的层数;11),树的高度;12),有序树和无序树;13),森林这些定义最好是记下来,反正我是没记下来,就没有都列举出来,书上应该都有的!介绍几个概念:结点(Node):树中的元素,包含数据项及若干指向其子树的分支。结点的度(Degree):结点拥有的子树数。叶子(Leaf):度为零的结点,也称端结点。孩子(Child):结点子树的根称为该结点的孩子结点。双亲(Parent):孩子结点的上层结点,称为这些结点的双亲。兄弟(Sibling):同一双亲的孩子。结点的层次:从根结点开始算起,根为第一层。深度(Depth): 树中结点的最大层次数。森林(Forest):m(m

3、0)棵互不相交的树的集合。二叉树 是n个结点的有限集,或者是空集,或者是由一个根节点及两颗互不相交的,分别称作这个根的左子树和右子树的二叉树组成。树 与 二叉树的区别: 1),树的结点可以有任意有限棵子树,而二叉树的任一结点至多只有两颗子树; 2),树中各子树没有子树之间的次序,而二叉树中将两颗子树明确地规定为左子树和右子树,并且当二叉树中一颗子树为空时,另一颗子树非空时,也要明确地指出它们的左右次序。二叉树的性质二叉树具有下列重要性质:性质1: 在二叉树的第i层上至多有2i-1个结点(i=1)。 采用归纳法证明此性质。当i=1时,只有一个根结点,2i-1=20 =1,命题成立。 现在假定对于

4、所有的j,1=j=1).深度为k的二叉树的最大的结点数 为二叉树中每层上的最大结点数之和,由性质1得到每层上的最大结点数:EkI=1(第i层上的最大结点数)= EkI=12i-1=2k 1性质3: 对任何一棵二叉树,如果其终端结点数为n0,度为2的结点数为n2,则n0n21。设二叉树中度为1的结点数为n1,二叉树中总结点数为N,因为二叉树中所有结点均小于或等于2,所以有:Nn0n1n2 (6-1)再看二叉树中的分支数,除根结点外,其余结点都有一个进入分支,设B为二叉树中的分支总数, 则有:NB1。由于这些分支都是由度为1和2的结点射出的,所有有: Bn1+2*n2 NB1n12n21 (62)

5、由式(61)和(62)得到: n0+n1+n2=n1+2*n2+1 n0n21性质4:具有n个结点的完全二叉树的深度为【log2n】1。 符号【x】表示不大于x的最大整数。 假设此二叉树的深度为k,则根据性质2及完全二叉树的定义得到:2k-11n=2k-1 或 2k-1=n2k取对数得到:k1=log2nk 因为k是整数。所以有:k【log2n】1。性质5: 如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到第【log2n】+1层,每层从左到右),则对任一结点i(1=i1,则其双亲是结点【i/2】。 (2)如果2in,则结点i为叶子结点,无左孩子;否则,其左孩子是结点2i。 (3)如

6、果2i1n,则结点i无右孩子;否则,其右孩子是结点2i1。二叉树的存储结构1.顺序存储结构 它是用一组连续的存储单元存储二叉树的数据元素。因此,必须把二叉树的所有结点安排成为一个恰当的序列,结点在这个序列中的相互位置能反映出结点之间的逻辑关系,用编号的方法:#define MAX-TREE-SIZE 100typedef TElemType SqBiTreeMAX-TREE-SIZE;SqBiTree bt; 从树根起,自上层至下层,每层自左至右的给所有结点编号缺点是有可能对存储空间造成极大的浪费,在最坏的情况下,一个深度为h且只有h个结点的右单支树确需要2h-1个结点存储空间。而且,若经常需

7、要插入与删除树中结点时,顺序存储方式不是很好!或:#define MaxSize 树中结点的最大数typedef struct int dataMaxSize; int node;SqBitree;SqBitree BT;BT就是一维数组,用它来存储一颗二叉树,每个数组元素存储二叉树的一个结点的数据信息。2.链式存储结构二叉树存储的链式结构可以使用二叉链表,它的每个结点有一个数据域和两个指针域,一个指针指向左孩子,另一个指针指向右孩子。二叉链表的结点结构描述如下: typedef struct node char data; struct node *lchild,*rchild; BinNo

8、de,*BinTree;给出一颗二叉树的二叉链表存储结构就是给出指向根结点的BinTree型头指针Root.在二叉链表中,容易找到一个结点的左右孩子,但是不易找结点的双亲。为了方便查找孩子和双亲,还可以使用三叉链表,其链表结点结构描述如下:typedef struct node char data; struct node *lchild,*rchild,*parent;BinList,*BinTree;3.二叉树二叉链表的生成算法1,非递归的朴素生成算法 根据二叉树的二叉链表存储结构,使用一种有辅助数组的创建二叉树的二叉链表的算法。该算法利用了二叉树的性质5,对任意二叉树,先按满二叉树对其进

9、行编号,然后按编号输入数据,构建二叉链表。算法思想: 把非完全二叉树及诶单按对应的完全二叉树进行编号,此时结点的编号并不连续。si中应该存放编号为i的结点的地址指针。/*样例输入: 1A 2B 3C 4D 5E 7F 00样例输出:ABDECF*/#include #include typedef struct node char data; struct node *lchild,*rchild;BinNode,*BinTree;BinTree create() int i,j; char x; BinTree s120,t = NULL,q; /t = NULL,定义指向根结点的指针 sc

10、anf(%d%c, &i, &x); while(i != 0 & x != 0) /结束条件 q = (BinTree)malloc(sizeof(BinNode); /产生一个新结点 q-data = x; /赋结点值 q-lchild = NULL; /赋左孩子值 q-rchild = NULL; /赋有孩子值 si = q; /用数组第i个单元存放指向此结点的指针 if(i = 1) t = q; /若是第1个,将t指向它为根 else /否则,为子树,计算子树的位置j j = i/2; if(i % 2)= 0) /j为偶数,是左子树 sj-lchild = q; else /j为奇

11、数,是右子树 sj-rchild = q; scanf(%d%c, &i, &x); return t; /返回一个指向根的指针void print(BinTree p) /先序输出二叉树 if(p != NULL) printf(%c,p-data); print(p-lchild); print(p-rchild); int main() BinTree root; root = create();/指针变量root指向一棵建立好的二叉树的二叉链表 print(root); return 0;-2,构造二叉链表的递归算法 根据二叉树的扩展先序序列,使用递归方法构造二叉链表该算法中输入的数据

12、是二叉树的扩展先序序列,即在先序序列中加入虚结点以示空指针的位置。算法思想: 算法的输入是二叉树的扩展先序序列,首先输入一个根节点,若输入的是空格 字符,表示该二叉树为空树,即 T = NULL;否则把输入的字符赋给T-data,之后,依次递归地建立它的左子树 T-lchild 和右子树 T-rchild.样例输入:ABD E C F 样例输出:ABDECF*/#include #include typedef struct Node char data; struct Node *lchild,*rchild;BinNode, *BinTree;void CreateBin(BinTree

13、*T) char ch; if(ch = getchar() = ) *T = NULL; else *T = (BinTree)malloc(sizeof(BinNode); (*T)-data = ch; CreateBin(&(*T)-lchild); CreateBin(&(*T)-rchild); void print(BinTree p) /先序输出二叉树 if(p != NULL) printf(%c,p-data); print(p-lchild); print(p-rchild); int main() BinTree root; CreateBin(&root); prin

14、t(root); return 0;-一,二叉树的递归遍历算法:假如以L、D、R分别表示遍历左子树、遍历根结点和遍历右子树,遍历整个二叉树则有DLR、LDR、LRD、DRL、RDL、RLD六种遍历方案。若规定先左后右,则只有前三种情况,分别规定为: DLR先(根)序遍历, LDR中(根)序遍历, LRD后(根)序遍历。1、先序遍历二叉树的操作定义为:若二叉树为空,则空操作;否则(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。2、中序遍历二叉树的操作定义为:若二叉树为空,则空操作;否则(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。3、后序遍历二叉树的操作定义为:若二

15、叉树为空,则空操作;否则(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。程序实现: 遍历二叉树是指以一定的顺序访问二叉树中的每个结点,并且每个结点仅被访问一次,所谓访问结点是对节点进行各种操作的简称。 遍历二叉树的过程,就是把二叉树的结点进行排列的过程。样例输入: 1A 2B 3C 4D 5E 7F 00样例输出:ABDECFDBEACFDEBFCA*/#include #include typedef struct node char data; struct node *lchild,*rchild;BinNode,*BinTree;BinTree create() int

16、i,j; char x; BinTree s120,t = NULL,q; /t = NULL,定义指向根结点的指针 scanf(%d%c, &i, &x); while(i != 0 & x != 0) /结束条件 q = (BinTree)malloc(sizeof(BinNode); /产生一个新结点 q-data = x; /赋结点值 q-lchild = NULL; /赋左孩子值 q-rchild = NULL; /赋有孩子值 si = q; /用数组第i个单元存放指向此结点的指针 if(i = 1) t = q; /若是第1个,将t指向它为根 else /否则,为子树,计算子树的位

17、置j j = i/2; if(i % 2)= 0) /j为偶数,是左子树 sj-lchild = q; else /j为奇数,是右子树 sj-rchild = q; scanf(%d%c, &i, &x); return t; /返回一个指向根的指针void preorder(BinTree p) /先序输出二叉树 if(p != NULL) printf(%c,p-data); preorder(p-lchild); preorder(p-rchild); void inorder(BinTree p) /中序输出二叉树 if(p != NULL) inorder(p-lchild); pr

18、intf(%c, p-data); inorder(p-rchild); void postorder(BinTree p) /后序输出二叉树 if(p != NULL) postorder(p-lchild); postorder(p-rchild); printf(%c, p-data); int main() BinTree root; root = create();/指针变量root指向一棵建立好的二叉树的二叉链表 preorder(root); puts(); inorder(root); puts(); postorder(root); puts(); return 0;-二,二

19、叉树的非递归遍历算法:为了写出非递归 遍历算法,我们可以观察到递归工作栈的状态变化。(1)当栈顶记录中的指针非空时,应遍历左子树,即指向左子树根的指针进栈。(2)若栈顶记录中的指针值为空,则应退至上一层,若是从左子树返回,则应访问当前层即栈顶指针上指针所指的根结点;(3)若是从右子树返回,则表明当前层的遍历结束,应继续退栈。由此可得以下两个中序遍历二叉树的非递归算法,先序遍历二叉树的非递归算法与此类似,但后序遍历二叉树的非递归算法要相对复杂一点。程序实现:/*样例输入:ABD E C F 样例输出:ABDECFDBEACFDEBFCA*/#include #include #define Ma

20、xSize 100typedef struct Node char data; struct Node *lchild,*rchild;BinNode,*BinTree;void CreateBin(BinTree *T) char ch; if(ch = getchar() = ) *T = NULL; else *T = (BinTree)malloc(sizeof(BinNode); (*T)-data = ch; CreateBin(&(*T)-lchild); CreateBin(&(*T)-rchild); void Visit(char ch) /访问结点值 printf(%c,

21、 ch);void PreOrder2(BinTree T) /先序遍历二叉树-非递归 int top=0; BinTree sMaxSize; BinTree p=T; do while(p) if(top MaxSize-1) return; s+top=p; Visit(p-data); p=p-lchild; if(top0) p=stop-; p=p-rchild; while(p | top0); printf(n);void InOrder2(BinTree T) /中序遍历二叉树-非递归 int top=0; BinTree sMaxSize; BinTree p=T; do

22、while(p) if(top MaxSize-1) return; s+top=p; p=p-lchild; if(top0) p=stop-; Visit(p-data); p=p-rchild; while(p | top0); printf(n);void PostOrder2(BinTree T) /后序遍历二叉树-非递归 BinTree sMaxSize; BinTree p=T,q; int top=0; while(p | top!=0) while(p) if(top MaxSize-1) return; top+; stop = p; p = p-lchild; if(to

23、p0) p = stop; if(p-rchild=NULL | p-rchild=q) Visit(p-data); q = p; top-; p = NULL; else p = p-rchild; printf(n);int main() BinTree root; CreateBin(&root); PreOrder2(root); /先序遍历二叉树-非递归 InOrder2(root); /中序遍历二叉树-非递归 PostOrder2(root); /后序遍历二叉树-非递归 return 0;三,二叉树的层次遍历算法: 在层次遍历中先访问的结点,其孩子结点也比后访问的结点的孩子结点先

24、访问,因此,许使用队列这种数据结构实现此算法。算法思想: 需要使用一个辅助队列,首先让根结点A入队,然后对队列进行操作,如果队列不空,队头结点出队,立即访问之,然后判断它是否有左,右孩子,如有孩子则让孩子结点入队,重复上述操作,直到队列为空为止。程序实现:样例输入:ABD#E#C#F#样例输出:ABCDEFABCDEF*/#include #include #define MaxSize 100typedef struct Node char data; struct Node *lchild,*rchild;BinNode,*BinTree;void CreateBin(BinTree *T

25、) /创建二叉树 char ch; if(ch = getchar() = #) *T = NULL; else if(!(*T=(BinTree)malloc(sizeof(BinNode) exit(1); (*T)-data = ch; CreateBin(&(*T)-lchild); CreateBin(&(*T)-rchild); void levelorder(BinTree p) /层次遍历二叉树 BinTree qMaxSize; int front = 0,rear = 0; if(p != NULL) rear+; qrear = p; while(front != rea

26、r) front+; p = qfront; printf(%c,p-data); if(p-lchild != NULL) rear+; qrear = p-lchild; if(p-rchild != NULL) rear+; qrear = p-rchild; printf(n);void Visit(char e)/访问函数 printf(%c,e);void LayerOrder(BinTree T) /层次遍历二叉树 BinTree qMaxSize; BinTree p; int front=0,rear=0; if(!T) return; if(rear+1)MaxSize) return; qrear+ = T; while(front data); if(p-lchil

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1