收藏 分享(赏)

清华大学严蔚敏版数据结构考研要点(精华版).doc

上传人:春华秋实 文档编号:3807442 上传时间:2018-11-19 格式:DOC 页数:29 大小:1.77MB
下载 相关 举报
清华大学严蔚敏版数据结构考研要点(精华版).doc_第1页
第1页 / 共29页
清华大学严蔚敏版数据结构考研要点(精华版).doc_第2页
第2页 / 共29页
清华大学严蔚敏版数据结构考研要点(精华版).doc_第3页
第3页 / 共29页
清华大学严蔚敏版数据结构考研要点(精华版).doc_第4页
第4页 / 共29页
清华大学严蔚敏版数据结构考研要点(精华版).doc_第5页
第5页 / 共29页
亲,该文档总共29页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、1、数据(Data) :是客观事物的符号表示。在计算机科学中指的是所有能输入到计算机中并被计算机程序处理的符号的总称。数据元素(Data Element) :是数据的基本单位,在程序中通常作为一个整体来进行考虑和处理。一个数据元素可由若干个数据项(Data Item)组成。数据项是数据的不可分割的最小单位。数据项是对客观事物某一方面特性的数据描述。数据对象(Data Object):是性质相同的数据元素的集合,是数据的一个子集。如字符集合 C=A,B,C, 。数据结构(Data Structure):是指相互之间具有(存在)一定联系(关系)的数据元素的集合。元素之间的相互联系( 关系) 称为逻

2、辑结构。 数据元素之间的逻辑结构有四种基本类型,如图1-3 所示。 集合:结构中的数据元素除了“同属于一个集合”外,没有其它关系。 线性结构:结构中的数据元素之间存在一对一的关系。 树型结构:结构中的数据元素之间存在一对多的关系。 图状结构或网状结构:结构中的数据元素之间存在多对多的关系。2、顺序结构:数据元素存放的地址是连续的; 链式结构:数据元素存放的地址是否连续没有要求。数据的逻辑结构和物理结构是密不可分的两个方面,一个算法的设计取决于所选定的逻辑结构,而算法的实现依赖于所采用的存储结构。在 C 语言中,用一维数组表示顺序存储结构;用结构体类型表示链式存储结构。3、 C 语言中用带指针的

3、结构体类型来描述typedef struct Lnode ElemType data; /*数据域,保存结点的值 */struct Lnode *next; /*指针域*/LNode; /*结点的类型 */4、循环队列为空:front=rear 。 循环队列满:(rear+1)%MAX_QUEUE_SIZE =front。5、性质 1:在非空二叉树中,第 i 层上至多有 2i-1 个结点 (i1) 。性质 2:深度为 k 的二叉树至多有 2k-1 个结点(k1) 。性质 3:对任何一棵二叉树,若其叶子结点数为 n0,度为 2 的结点数为 n2,则n0=n2+1。一棵深度为 k 且有 2k-1

4、个结点的二叉树称为满二叉树(Full Binary Tree)。完全二叉树的特点:若完全二叉树的深度为 k ,则所有的叶子结点都出现在第 k 层或k-1 层。对于任一结点,如果其右子树的最大层次为 l,则其左子树的最大层次为 l 或 l+1。性质 4:n 个结点的完全二叉树深度为: 2n +1。性质 5:若对一棵有 n 个结点的完全二叉树(深度为 2n+1)的结点按层(从第 1 层到第 2n +1 层)序自左至右进行编号,则对于编号为 i(1 in) 的结点: 若 i=1:则结点 i 是二叉树的根,无双亲结点;否则,若 i1,则其双亲结点编号是 i/2 。 如果 2in:则结点 i 为叶子结点

5、,无左孩子;否则,其左孩子结点编号是 2i。 如果 2i+1n:则结点 i 无右孩子;否则,其右孩子结点编号是 2i+1。6、线索二叉树:设一棵二叉树有 n 个结点,则有 n-1 条边(指针连线) , 而 n 个结点共有2n 个指针域(Lchild 和 Rchild) ,显然有 n+1 个空闲指针域未用。则可以利用这些空闲的指针域来存放结点的直接前驱和直接后继信息。7、 Huffman 树:具有 n 个叶子结点(每个结点的权值为 wi) 的二叉树不止一棵,但在所有的这些二叉树中,必定存在一棵 WPL 值最小的树,称这棵树为 Huffman树(或称最优树) 。8、完全无向图:对于无向图,若图中顶

6、点数为 n ,用 e 表示边的数目,则 e 0,n(n-1)/2 。具有 n(n-1)/2 条边的无向图称为完全无向图。完全有向图:对于有向图,若图中顶点数为 n ,用 e 表示弧的数目,则 e0,n(n-1) 。具有 n(n-1)条边的有向图称为完全有向图。生成树、生成森林:一个连通图(无向图) 的生成树是一个极小连通子图,它含有图中全部n 个顶点和只有足以构成一棵树的 n-1 条边,称为图的生成树关于无向图的生成树的几个结论:1) 一棵有 n 个顶点的生成树有且仅有 n-1 条边;2) 如果一个图有 n 个顶点和 小于 n-1 条边,则是非连通图;3) 如果多于 n-1 条边,则一定有环;

7、4) 有 n-1 条边的图不一定是生成树。9、最小生成树(Minimum Spanning Tree) :带权连通图中代价最小的生成树称为最小生成树。 最小生成树在实际中具有重要用途,如设计通信网。设图的顶点表示城市,边表示两个城市之间的通信线路,边的权值表示建造通信线路的费用。n 个城市之间最多可以建 n(n-1)/2 条线路,如何选择其中的 n-1 条,使总的建造费用最低?10、 工程完成最短时间:从起点到终点的最长路径长度(路径上各活动持续时间之和) 。长度最长的路径称为关键路径,关键路径上的活动称为关键活动。关键活动是影响整个工程的关键。 11、查找方法比较顺序查找 折半查找 分块查找

8、ASL 最大 最小 两者之间表结构 有序表、无序表 有序表 分块有序表存储结构顺序存储结构线性链表顺序存储结构顺序存储结构线性链表12、 在随机情况下,二叉排序树的平均查找长度 ASL 和(n)(树的深度)是等数量级的。二叉排序树(Binary Sort Tree 或 Binary Search Tree) 的定义为:二叉排序树或者是空树,或者是满足下列性质的二叉树。(1) :若左子树不为空,则左子树上所有结点的值(关键字) 都小于根结点的值;(2) :若右子树不为空,则右子树上所有结点的值(关键字) 都大于根结点的值;(3) :左、右子树都分别是二叉排序树。结论:若按中序遍历一棵二叉排序树,

9、所得到的结点序列是一个递增序列。13、平衡二叉树或者是空树,或者是满足下列性质的二叉树。:左子树和右子树深度之差的绝对值不大于 1;:左子树和右子树也都是平衡二叉树。平衡因子(Balance Factor) :二叉树上结点的左子树的深度减去其右子树深度称为该结点的平衡因子。平衡二叉排序树上进行查找的平均查找长度和2n 是一个数量级的,平均时间复杂度为O(2n)。四种平衡化旋转,其正确性容易由“遍历所得中序序列不变 ”来证明。并且,无论是哪种情况,平衡化旋转处理完成后,形成的新子树仍然是平衡二叉排序树,且其深度和插入前以 a 为根结点的平衡二叉排序树的深度相同。所以,在平衡二叉排序树上因插入结点

10、而失衡,仅需对失衡子树做平衡化旋转处理。14、 一棵 m 阶 B_树,或者是空树,或者是满足以下性质的 m 叉树: 根结点或者是叶子,或者至少有两棵子树,至多有 m 棵子树; 除根结点外,所有非终端结点至少有 m/2 棵子树,至多有 m 棵子树; 所有叶子结点都在树的同一层上; 每个结点应包含如下信息:(n,A 0,K 1,A 1,K 2,A 2, ,K n,A n)其中 Ki(1in)是关键字,且 Kilength; i+) L-R0=L-Ri; j=i-1; /* 设置哨兵 */while( LT(L-R0.key, L-Rj.key) ) L-Rj+1=L-Rj;j-; /* 查找插入位

11、置 */L-Rj+1=L-R0; /* 插入到相应位置 */ =折半插入排序当将待排序的记录 Ri 插入到已排好序的记录子表 R1i-1中时,由于 R1, R2 , Ri-1已排好序,则查找插入位置可以用 “折半查找 ”实现,则直接插入排序就变成为折半插入排序。从时间上比较,折半插入排序仅仅减少了关键字的比较次数,却没有减少记录的移动次数,故时间复杂度仍然为 O(n2) 。排序示例:设有一组关键字 30, 13, 70, 85, 39, 42, 6, 20,采用折半插入排序方法排序的过程 算法实现 void Binary_insert_sort(Sqlist *L) int i, j, low

12、, high, mid ;for (i=2; ilength; i+) L-R0=L-Ri; /* 设置哨兵 */ low=1 ; high=i-1 ; while (lowR0.key, L-Rmid.key) )high=mid-1 ;else low=mid+1 ; /* 查找插入位置 */for (j=i-1; j=high+1; j-)L-Rj+1=L-Rj; L-Rhigh+1=L-R0; /* 插入到相应位置 */= 2-路插入排序排序示例:设有初始关键字集合49, 38, 65, 13, 97, 27, 76 ,采用 2-路插入排序的过程例:设有关键字集合49, 38, 65,

13、 97, 76, 13, 27, 49 ,采用表插入排序的过程=希尔排序(Shell Sort,又称缩小增量法)是一种分组插入排序方法。排序示例 设有 10 个待排序的记录,关键字分别为 9, 13, 8, 2, 5, 13, 7, 1, 15, 11,增量序列是 5, 3, 1,希尔排序的过程:算法实现先给出一趟希尔排序的算法,类似直接插入排序。void shell_pass(Sqlist *L, int d)/* 对顺序表 L 进行一趟希尔排序, 增量为 d */ int j, k ;for (j=d+1; jlength; j+) L-R0=L-Rj ; /* 设置监视哨兵 */k=j-

14、d ;while (k0 k=k-d ; L-Rk+j=L-R0 ;void shell_sort(Sqlist *L, int dk, int t)/* 按增量序列 dk0 t-1,对顺序表 L 进行希尔排序 */ int m ;for (m=0; mlength; j+) /* 共有 n-1 趟排序 */ flag=TRUE ; for (k=1; klength-j; k+) /* 一趟排序 */ if (LT(L-Rk+1.key, L-Rk.key ) ) flag=FALSE ; L-R0=L-Rk ; L-Rk=L-Rk+1 ; L-Rk+1=L-R0 ; if (flag=TR

15、UE) break ;算法分析:时间复杂度:最好情况(正序 ):比较次数: n-1;移动次数:0;最坏情况(逆序 ):故时间复杂度:T(n)=O(n)空间复杂度:S(n)=O(1)=快速排序的平均时间复杂度是:T(n)=O(n 2n) 从所需要的附加空间来看,快速排序算法是递归调用,系统内用堆栈保存递归参数,当每次划分比较均匀时,栈的最大深度为2n+1 。 快速排序的空间复杂度是:S(n)=O(2n)从排序的稳定性来看,快速排序是不稳定的。一趟排序示例 设有 6 个待排序的记录,关键字分别为 29, 38, 22, 45, 23, 67,一趟快速排序的过程算法实现 一趟快速排序算法的实现int

16、 quick_one_pass(Sqlist *L , int low, int high)L-R0=L-Ri ; /* R0作为临时单元和哨兵 */do while (LQ(L-R0.key, L-Rj.key)if (ji) L-Ri=L-Rj ; i+; while (LQ(L-Ri.key, L-R0.key)if (ji) L-Rj=L-Ri ; j-; while(i!=j) ; /* i=j 时退出扫描 */L-Ri=L-R0 ; return(i) ;递归算法 void quick_Sort(Sqlist *L , int low, int high) int k ;if (l

17、owlength; m+) k=m ; for (n=m+1; nlength; n+)if ( LT(L-Rn.key, L-Rk.key) ) k=n ;if (k!=m) /* 记录交换 */ L-R0=L-Rm; L-Rm=L-Rk;L-Rk=L-R0; 算法分析整个算法是二重循环:外循环控制排序的趟数,对 n 个记录进行排序的趟数为 n-1 趟;内循环控制每一趟的排序。进行第 i 趟排序时,关键字的比较次数为 n-i,则: 时间复杂度是:T(n)=O(n 2)空间复杂度是:S(n)=O(1)从排序的稳定性来看,直接选择排序是不稳定的。=堆的定义是 n 个元素的序列 H=k1, k2

18、, kn ,满足: 堆的性质 堆是一棵采用顺序存储结构的完全二叉树, k1 是根结点; 堆的根结点是关键字序列中的最小 (或最大 )值,分别称为小 (或大 )根堆; 从根结点到每一叶子结点路径上的元素组成的序列都是按元素值 (或关键字值 )非递减(或非递增 )的;(4)堆中的任一子树也是堆。利用堆顶记录的关键字值最小 (或最大 )的性质,从当前待排序的记录中依次选取关键字最小 (或最大 )的记录,就可以实现对数据记录的排序,这种排序方法称为堆排序。堆排序思想 对一组待排序的记录,按堆的定义建立堆; 将堆顶记录和最后一个记录交换位置,则前 n-1 个记录是无序的,而最后一个记录是有序的; 堆顶记

19、录被交换后,前 n-1 个记录不再是堆,需将前 n-1 个待排序记录重新组织成为一个堆,然后将堆顶记录和倒数第二个记录交换位置,即将整个序列中次小关键字值的记录调整(排除) 出无序区; 重复上述步骤,直到全部记录排好序为止。结论:排序过程中,若采用小根堆,排序后得到的是非递减序列;若采用大根堆,排序后得到的是非递增序列。堆排序算法实现堆的根结点是关键字最小的记录,输出根结点后,是以序列的最后一个记录作为根结点,而原来堆的左、右子树都是堆,则进行一次筛选就可以成为堆。void Heap_Sort(Sqlist *H) int j ;for (j=H-length/2; j0; j-)Heap_a

20、djust(H, j , H-length) ; /* 初始建堆 */for (j=H-length/2; j=1; j-) H-R0=H-R1 ; H-R1=H-Rj ;H-Rj=H-R0 ; /* 堆顶与最后一个交换 */Heap_adjust(H, 1, j-1) ; 堆排序的比较次数的数量级为: T(n)=O(n 2n);而附加空间就是交换时所用的临时空间,故空间复杂度为: S(n)=O(1)=归并(Merging) :是指将两个或两个以上的有序序列合并成一个有序序列。若采用线性表(无论是那种存储结构 )易于实现,其时间复杂度为 O(m+n) 。归并排序的算法开始归并时,每个记录是长度

21、为 1 的有序子序列,对这些有序子序列逐趟归并,每一趟归并后有序子序列的长度均扩大一倍;当有序子序列的长度与整个记录序列长度相等时,整个记录序列就成为有序序列。算法是: void Merge_sort(Sqlist *L, RecType DR) int d=1 ;while(dlength) Merge_pass(L-R, DR, d, L-length) ;Merge_pass(DR, L-R, 2*d, L-length) ;d=4*d ;具有 n 个待排序记录的归并次数是 2n,而一趟归并的时间复杂度为 O(n),则整个归并排序的时间复杂度无论是最好还是最坏情况均为 O(n 2n)。在

22、排序过程中,使用了辅助向量DR,大小与待排序记录空间相同,则空间复杂度为 O(n)。归并排序是稳定的。=各种内部排序的比较:各种内部排序按所采用的基本思想(策略) 可分为:插入排序、交换排序、选择排序、归并排序和基数排序,它们的基本策略分别是:1 插入排序:依次将无序序列中的一个记录,按关键字值的大小插入到已排好序一个子序列的适当位置,直到所有的记录都插入为止。具体的方法有:直接插入、表插入、2-路插入和 shell 排序。 2 交换排序:对于待排序记录序列中的记录,两两比较记录的关键字,并对反序的两个记录进行交换,直到整个序列中没有反序的记录偶对为止。具体的方法有:冒泡排序、快速排序。3 选

23、择排序:不断地从待排序的记录序列中选取关键字最小的记录,放在已排好序的序列的最后,直到所有记录都被选取为止。具体的方法有:简单选择排序、堆排序。4 归并排序:利用“归并”技术不断地对待排序记录序列中的有序子序列进行合并,直到合并为一个有序序列为止。5 基数排序:按待排序记录的关键字的组成成分(“位”)从低到高(或从高到低)进行。每次是按记录关键字某一“位”的值将所有记录分配到相应的桶中,再按桶的编号依次将记录进行收集,最后得到一个有序序列。各种内部排序方法的性能比较如下表。文件的基本概念 数据项(Item 或 field) :数据文件中最小的基本单位,反映实体某一方面的特征 属性的数据表示。

24、记录(Record) :一个实体的所有数据项的集合。 用来标识一个记录的数据项集合(一个或多个)称为关键字项 (Key) ,关键字项的值称为关键字;能唯一标识一个记录的关键字称为主关键字(Primary Key),其它的关键字称为次关键字 (Secondary Key) 。 利用外存对数据文件进行排序称为外部排序。算法部分:素数的判断算法。Void prime( int n)/* n 是一个正整数 */ int i=2 ; while ( (n% i)!=0 elseprintf(“-冒泡排序法。Void bubble_sort(int a,int n) change=false;for (i

25、=n-1; change=TURE; i1 -i)for (j=0; jaj+1) aj aj+1 ; change=TURE ; 最好情况:0 次 最坏情况:1+2+3+n-1=n(n-1)/2 平均时间复杂度为: O(n2) -算法说明 :算法中 pa , pb 分别是待考察的两个链表的当前结点, pc 是合并过程中合并的链表的最后一个结点。LNode *Merge_LinkList(LNode *La, LNode *Lb)/* 合并以 La, Lb 为头结点的两个有序单链表 */ LNode *Lc, *pa , *pb , *pc, *ptr ;Lc=La ; pc=La ; pa=

26、La-next ; pb=Lb-next ;while (pa!=NULL pc=pa ; pa=pa-next ; /* 将 pa 所指的结点合并, pa 指向下一个结点 */if (pa-datapb-data) pc-next=pb ; pc=pb ; pb=pb-next ; /* 将 pa 所指的结点合并, pa 指向下一个结点 */ if (pa-data=pb-data) pc-next=pa ; pc=pa ; pa=pa-next ; ptr=pb ; pb=pb-next ; free(ptr) ; /* 将 pa 所指的结点合并, pb 所指结点删除 */ if (pa!

27、=NULL) pc-next=pa ;else pc-next=pb ; /*将剩余的结点链上*/free(Lb) ;return(Lc) ;采用静态顺序栈方式实现 void conversion(int n , int d) /*将十进制整数 N 转换为 d(2 或 8)进制数*/ SqStack S ; int k, *e ;S=Init_Stack();while (n0) k=n%d ; push(S , k) ; n=n/d ; /* 求出所有的余数,进栈 */while (S.top!=0) /* 栈不空时出栈,输出 */ pop(S, e) ; printf(“%1d” , *e

28、) ; 求转置矩阵的算法如下:void TransMatrix(TMatrix a , TMatrix b) int p , q , col ;b.rn= ; =a.rn ; b.tn=a.tn ;/* 置三元组表 b.data 的行、列数和非 0 元素个数 */if (b.tn=0) printf(“ The Matrix A=0n” );else q=0;for (col=1; coldata) ; /* 访问根结点 */PreorderTraverse(T-Lchild) ;PreorderTraverse(T-Rchild) ; 非递归算法 设 T 是指向二叉树根结点的指针变量,非递归

29、算法是:若二叉树为空,则返回;否则,令 p=T; 访问 p 所指向的结点; q=p-Rchild ,若 q 不为空,则 q 进栈; p=p-Lchild ,若 p 不为空,转 (1),否则转 (4); 退栈到 p ,转 (1),直到栈空为止。算法实现:#define MAX_NODE 50void PreorderTraverse( BTNode *T) BTNode *StackMAX_NODE ,*p=T, *q ;int top=0 ;if (T=NULL) printf(“ Binary Tree is Empty!n”) ;else do visit( p- data ) ; q=p

30、-Rchild ; if ( q!=NULL ) stack+top=q ;p=p-Lchild ; if (p=NULL) p=stacktop ; top- ; while (p!=NULL) ;=中序遍历的递归算法void InorderTraverse(BTNode *T) if (T!=NULL) InorderTraverse(T-Lchild) ;visit(T-data) ; /* 访问根结点 */InorderTraverse(T-Rchild) ;非递归算法 设 T 是指向二叉树根结点的指针变量,非递归算法是:若二叉树为空,则返回;否则,令 p=T 若 p 不为空, p 进

31、栈, p=p-Lchild ; 否则 (即 p 为空 ),退栈到 p,访问 p 所指向的结点; p=p-Rchild ,转 (1);直到栈空为止。算法实现:#define MAX_NODE 50void InorderTraverse( BTNode *T) BTNode *StackMAX_NODE ,*p=T ;int top=0 , bool=1 ;if (T=NULL) printf(“ Binary Tree is Empty!n”) ;else do while (p!=NULL) stack+top=p ; p=p-Lchild ; if (top=0) bool=0 ;else

32、 p=stacktop ; top- ;visit( p-data ) ; p=p-Rchild ; while (bool!=0) ;=后序遍历的递归算法void PostorderTraverse(BTNode *T) if (T!=NULL) PostorderTraverse(T-Lchild) ;PostorderTraverse(T-Rchild) ; visit(T-data) ; /* 访问根结点 */ 非递归算法 在后序遍历中,根结点是最后被访问的。因此,在遍历过程中,当搜索指针指向某一根结点时,不能立即访问,而要先遍历其左子树,此时根结点进栈。当其左子树遍历完后再搜索到该根

33、结点时,还是不能访问,还需遍历其右子树。所以,此根结点还需再次进栈,当其右子树遍历完后再退栈到到该根结点时,才能被访问。因此,设立一个状态标志变量 tag : 0 : 结点暂不能访问1 : 结点可以被访问其次,设两个堆栈 S1、 S2 , S1 保存结点, S2 保存结点的状态标志变量 tag 。 S1 和 S2 共用一个栈顶指针。设 T 是指向根结点的指针变量,非递归算法是:若二叉树为空,则返回;否则,令 p=T; 第一次经过根结点 p,不访问: p 进栈 S1 , tag 赋值 0,进栈 S2, p=p-Lchild 。 若 p 不为空,转 (1),否则,取状态标志值 tag : 若 ta

34、g=0:对栈 S1,不访问,不出栈;修改 S2 栈顶元素值 (tag 赋值 1) ,取 S1 栈顶元素的右子树,即 p=S1top-Rchild ,转 (1); 若 tag=1: S1 退栈,访问该结点;直到栈空为止。算法实现: #define MAX_NODE 50void PostorderTraverse( BTNode *T) BTNode *S1MAX_NODE ,*p=T ;int S2MAX_NODE , top=0 , bool=1 ;if (T=NULL) printf(“Binary Tree is Empty!n”) ;else dowhile (p!=NULL) S1+

35、top=p ; S2top=0 ; p=p-Lchild ; if (top=0) bool=0 ;else if (S2top=0) p=S1top-Rchild ; S2top=1 ; else p=S1top ; top- ;visit( p-data ) ; p=NULL ; /* 使循环继续进行而不至于死循环 */ while (bool!=0) ;=设 T 是指向根结点的指针变量, 层次遍历非递归 算法是:若二叉树为空,则返回;否则,令 p=T, p 入队; 队首元素出队到 p; 访问 p 所指向的结点; 将 p 所指向的结点的左、右子结点依次入队。直到队空为止。#define M

36、AX_NODE 50void LevelorderTraverse( BTNode *T) BTNode *QueueMAX_NODE ,*p=T ;int front=0 , rear=0 ;if (p!=NULL) Queue+rear=p; /* 根结点入队 */while (frontdata );if (p-Lchild!=NULL)Queue+rear=p; /* 左结点入队 */if (p-Rchild!=NULL)Queue+rear=p; /* 左结点入队 */=利用层次遍历算法可以直接求得 二叉树的深度 。算法实现:#define MAX_NODE 50int search

37、_depth( BTNode *T) BTNode *StackMAX_NODE ,*p=T;int front=0 , rear=0, depth=0, level ;/* level 总是指向访问层的最后一个结点在队列的位置 */if (T!=NULL) Queue+rear=p; /* 根结点入队 */level=rear ; /* 根是第 1 层的最后一个节点 */while (frontLchild!=NULL)Queue+rear=p; /* 左结点入队 */if (p-Rchild!=NULL)Queue+rear=p; /* 左结点入队 */if (front=level) /

38、* 正访问的是当前层的最后一个结点 */ depth+ ; level=rear ; = 先序线索化二叉树void preorder_Threading(BiThrNode *T) BiThrNode *stackMAX_NODE;BiThrNode *last=NULL, *p ;int top=0 ;if (T!=NULL) stack+top=T;while (top0) p=stacktop- ;if (p-Lchild!=NULL) p-Ltag=0 ;else p-Ltag=1 ; p-Lchild!=last ; if (last!=NULL)if (last-Rchild!=N

39、ULL) last-Rtag=0 ;else last-Rtag=1 ; last-Rchild!=p ; last=p ;if (p-Rchild!=NULL) stack+top=p-Rchild ; if (p-Lchild!=NULL)stack+top=p-Lchild ;Last-Rtag=1; /* 最后一个结点是叶子结点 */=中序线索化二叉树void inorder_Threading(BiThrNode *T) BiThrNode *stackMAX_NODE;BiThrNode *last=NULL, *p=T ;int top=0 ;while (p!=NULL|top

40、0)if (p!=NULL) stack+top=p; p=p-Lchild; else p=stacktop- ;if (p-Lchild!=NULL) p-Ltag=0 ;else p-Ltag=1 ; p-Lchild!=last ; if (last!=NULL)if (last-Rchild!=NULL) last-Rtag=0 ;else last-Rtag=1 ; last-Rchild!=p ; last=p ; P=p-Rchild; last-Rtag=1; /* 最后一个结点是叶子结点 */= Huffman 树的生成算法实现void Create_Huffman(uns

41、igned n, HTNode HT , unsigned m)/* 创建一棵叶子结点数为 n 的 Huffman 树 */ unsigned int w ; int k , j ;for (k=1 ; kAdjListv.firstarc; /* 链表的第一个结点 */while (p!=NULL) if (!Visitedp-adjvex) DFS(G, p-adjvex) ;/* 从 v 的未访问过的邻接顶点出发深度优先搜索 */p=p-nextarc ; void DFS_traverse_Grapg(ALGraph *G) int v ;for (v=0 ; vvexnum ; v+

42、)Visitedv=FALSE ; /* 访问标志初始化 */ p=G-AdjListv.firstarc ;for (v=0 ; vvexnum ; v+)if (!Visitedv) DFS(G , v);= typedef emnu FALSE , TRUE BOOLEAN ;BOOLEAN VisitedMAX_VEX ;typedef struct Queue int elemMAX_VEX ;int front , rear ;Queue ; /* 定义一个队列保存将要访问顶点 */void BFS_traverse_Grapg(ALGraph *G) int k ,v , w ;

43、LinkNode *p ; Queue *Q ;Q=(Queue *)malloc(sizeof(Queue) ;Q-front=Q-rear=0 ; /* 建立空队列并初始化 */for (k=0 ; kvexnum ; k+)Visitedk=FALSE ; /* 访问标志初始化 */for (k=0 ; kvexnum ; k+) v=G-AdjListk.data ; /* 单链表的头顶点 */if (!Visitedv) /* v 尚未访问 */ Q-elem+Q-rear=v ; /* v 入对 */while (Q-front!=Q-rear) w=Q-elem+Q-front ;Visitedw=TRUE ; /* 置访问标志 */Vi

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报