1、(完整word版)数据结构(C语言版)期末复习汇总数据结构(C语言版) 期末复习汇总第一章 绪论数据结构:是一门研究非数值计算程序设计中的操作对象,以及这些对象之间的关系和操作的学科。数据结构是一门综合性的专业课程,是一门介于数学、计算机硬件、计算机软件之间的一门核心课程。是设计和实现编译系统、操作系统、数据库系统及其他系统程序和大型应用程序的基础。数据:是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。如数学计算中用到的整数和实数,文本编辑中用到的字符串,多媒体程序处理的图形、图像、声音及动画等通过特殊编码定义后的数据。数据的逻辑结构划分:线、树、图算法的定义及特性
2、算法:是为了解决某类问题而规定的一个有限长的操作序列。五个特性:有穷性、确定性、可行性、输入、输出评价算法优劣的基本标准(4个):正确性、可读性、健壮性、高效性及低存储量第二章 线性表线性表的定义和特点:线性表:由n(n0)个数据特性相同的元素构成的有限序列。线性表中元素个数n(n0)定义为线性表的长度,n=0时称为空表。非空线性表或线性结构,其特点:(1)存在唯一的一个被称作“第一个”的数据元素;(2)存在唯一的一个被称作“最有一个”的数据元素;(3)除第一个之外,结构中的每个数据元素均只有一个前驱;(4)除最后一个之外,结构中的每个数据元素均只有一个后继。顺序表的插入:n个元素在i位插入,
3、应移动(n-i+1)位元素。顺序表存储结构的优缺点:优点:逻辑相邻,物理相邻;可随机存取任一元素;存储空间使用紧凑;缺点:插入、删除操作需要移动大量的元素;预先分配空间需按最大空间分配,利用不充分;表容量难以扩充;线性表的应用:一般线性表的合并:算法2.1:LA=(7,5,3,11) LB=(2,6,3)合并后 LA=(7,5,3,11,2,6)算法思想:扩大线性表LA,将存在于线性表LB中而不存在于线性表LA中的数据元素插入到线性表LA中去。只要从线性表LB中依次取得每个数据元素,并依值在线性表LA中进行查访,若不存在,则插入之。有序表的合并:算法2.2:LA=(3,5,8,11) LB=(
4、2,6,8,9,11,15,20)则 LC=(2,3,5,6,8,9,11,11,15,20)算法思想:首先创建一个空表LC,通过比较指针pa和pb所指向的元素的值,依次从LA或LB中“摘取”元素值较小的结点插入到LC表的最后,当其中一个表变空是,说明此表的元素已归并完,则只要将另一个非空表的剩余结点依次插入在LC表的最后即可。线性链表:线性链表的插入:插入元素师,指针的指向变化:上述指针修改用语句描述即为:s-next=p-next; p-next=s;单链表的插入:void insertnode(linklist head,datetype x,int i) listnode * p,*q
5、; p=getnode(head,i-1); if(p=NULL) error(position error); q=(listnode *) malloc(sizeof(listnode); qdata=x; qnext=pnext; pnext=q; 课本中:s=new LNode;s-data =e;s-next=p-next;p-next=s;线性链表的删除:删除元素,指针的指向变化:上述指针修改用语句描述即为:p-next=p-next-next;单链表的删除:void deletelist(linklist head, int i) listnode * p, *r; p=getn
6、ode(head,i-1); if(p= =NULL | pnext= =NULL) return ERROR; r=pnext; pnext=rnext; free( r ) ; 课本中:q=p-next;p-next=q-next;单链表特点:它是一种动态结构,整个存储空间为多个链表共用;不需预先分配空间;指针占用额外存储空间;不能随机存取,查找速度慢。第三章 栈和队列栈的类型定义:栈(Stack)是限制在表的一端进行插入和删除运算的线性表,通常称插入、删除的这一端为栈顶(Top),另一端为栈底(Bottom)。当表中没有元素时称为空栈。假设栈S=(a1,a2,a3,an),则a1称为栈底
7、元素,an为栈顶元素。栈中元素按a1,a2,a3,an的次序进栈,退栈的第一个元素应为栈顶元素。即,栈的修改是按后进先出的原则进行的。因此,栈称为后进先出表(LIFO)。栈的进栈、出栈顺序:例:对于一个栈,给出输入项A、B、C,如果输入项序列由ABC组成,试给出所有可能的输出序列。 A进 A出 B进 B出 C进 C出 ABC A进 A出 B进 C进 C出 B出 ACB A进 B进 B出 A出 C进 C出 BAC A进 B进 B出 C进 C出 A出 BCA A进 B进 C进 C出 B出 A出 CBA不可能产生输出序列CAB栈的应用:数值转换大题算法思想:首先将按照上述计算过程中得到的八进制树的各
8、位依次进栈,然后将栈中的八进制数依次出栈输出,输出结果就是该是十进制数转换得到的八进制数。N=(N div d)d + N mod d (其中:div 为整除运算,mod 为求余运算)例如 (1348)10=(2504)8,其运算过程如下:N N div 8 N mod 81348 168 4168 21 021 2 52 0 2算法:【此为课件算法同课本算法一致】 void conversion( ) initstack ( s );/构造空栈 scanf ( “ % ” , n); while( n ) push ( s , n % 8 ); n = n / 8; while( ! Sta
9、ckempty ( s )/当栈非空时 pop ( s , e ); printf ( “ % d ” , e ); /conversion队列的类型定义:定义:队列是限定只能在表的一端进行插入,在表的另一端进行删除的线性表队尾(rear):允许插入的一端队头(front):允许删除的一端队列特点:先进先出 ( FIFO )第四章 串、数组和广义表串的类型定义:串是字符串的简称。它是一种在数据元素的组成上具有一定约束条件的线性表,即要求组成线性表的所有数据元素都是字符,所以,人们经常又这样定义串:串是一个有穷字符序列。串一般记作: s= “a1a2.an” (n0) 其中,s是串的名称,用双引
10、号(“”)括起来的字符序列是串的值;ai可以是字母、数字或其他字符;串中字符的数目n被称作串的长度。当n=0时,串中没有任何字符,其串的长度为0,通常被称为空串。子串、主串:串中任意连续的字符组成的子序列被称为该串的子串。包含子串的串又被称为该子串的主串。广义表的定义:广义表是n(n=0)个元素a1,a2,a3,an的有限序列,其中ai或者是原子项,或者是一个广义表。通常记作LS=(a1,a2,a3,an)。LS是广义表的名字,n为它的长度。若ai是广义表,则称它为LS的子表。广义表的结构特点:1) 广义表的元素可以是子表,而子表的元素还可以是子表广义表是一个多层次的结构2) 广义表可为其他广
11、义表所共享3) 广义表可以是一个递归的表,即广义表也可以是其本身的一个子表广义表的两个重要运算:取表头GetHead(LS),取表尾GetTail(LS)任何一个非空广义表 LS = ( a1, a2, , an )均可分解为 表头 Head(LS) = a1 和 表尾 Tail(LS) = ( a2, , an )两部分。例如:已知广义表LS=(a,(b,c,d),c),运用GetHead和GetTail函数取出原子d的运算过程为:GetHead(GetTail(GetTail(GetHead(GetTail(LS)第五章 树和二叉树数的定义: 树(tree)是n(n0)个结点的有限集T,其
12、中:有且仅有一个特定的结点,称为树的根(root);当n1时,其余结点可分为m(m0)个互不相交的有限集T1,T2,Tm,其中每一个集合本身又是一棵树,称为根的子树(subtree)。特点:树中至少有一个结点:根树中各子树是互不相交的集合线性结构与树形结构的区别线性结构树形结构第一个数据元素(无前驱) 根结点 (无前驱)最后一个数据元素(无后继) 多个叶子结点(无后继)其它数据元素(一个前驱,一个后继)其它数据元素(一个前驱、多个后继)树的基本术语:结点(node) :表示树中的元素,包括数据元素及若干指向其子树的分支结点的度(degree) :结点拥有的子树数树的度 : 一棵树中最大的结点度
13、数叶子(leaf) :度为0的结点(终端结点)孩子(child) :结点子树的根称为该结点的双亲(parents) :孩子结点的上层结点叫该结点的兄弟(sibling) :同一双亲的孩子子孙 : 以某结点为根的子树中的所有结点都被称为是该结点的祖先 :从根结点到该结点路径上的所有结点堂兄弟 :双亲在同一层的结点互为结点的层次(level) : 从根结点算起,根为第一层,它的孩子为第二层深度(depth) : 树中结点的最大层次数森林(forest) : m(m0)棵互不相交的树的集合有序树、无序树 : 如果树中每棵子树从左向右的排列拥有一定的顺序,不得互换,则称为有序树,否则称为无序树对于课本
14、P96树形图:结点A的度:3结点B的度:2结点M的度:0结点A的层次:1结点M的层次:4结点B,C,D为兄弟结点K,L为兄弟叶子:K,L,F,G,M,I,J结点A的孩子:B,C,D结点B的孩子:E,F结点I的双亲:D结点L的双亲:E结点F,G为堂兄弟结点A是结点F,G的祖先树的深度:4树的度:3二叉树的定义:二叉树是n(n0)个结点的有限集,它或为空树(n=0),或由一个根结点和两棵分别称为左子树和右子树的互不相交的二叉树构成。特点每个结点至多有二棵子树(即不存在度大于2的结点);二叉树的子树有左、右之分,且其次序不能任意颠倒。二叉树的性质:性质1:在二叉树的第i层上最多有2i-1个结点(i1
15、);性质2:深度为K的二叉树最多有2K-1个结点 (K1);性质3: 对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1;完全二叉树定义:一棵深度为h,具有n个结点的二叉树,若将它与一棵同深度的满二叉树中的所有结点按从上到下,从左到右的顺序分别进行编号,且该二叉树中的每个结点分别与满二叉树中编号为1n的结点位置一一对应,则称这棵二叉树为完全二叉树。特点:叶子结点只可能在层次最大的两层上出现;对任一结点,若其右分支下子孙的最大层次为L,则其左分支下子孙的最大层次必为L或L+1。性质4:具有n个结点的完全二叉树的深度为log2n+1。(其中,log2n 的结果是不大
16、于log2n的最大整数。)性质5:对于有n个结点的完全二叉树中的所有结点按从上到下,从左到右的顺序进行编号,则对任意一个结点i (1in),都有:(1)如果i=1,则结点i是这棵完全二叉树的根,没有双亲。否则其双亲结点的编号为 i/2;(2)如果2in,则结点i没有左孩子。否则其左孩子结点的编号为2i;(3)如果2i+1n,则结点i没有右孩子。否则其右孩子结点的编号为2i+1。 遍历二叉树:先序遍历:先访问根结点,然后分别先序遍历左子树、右子树【包络法】中序遍历:先中序遍历左子树,然后访问根结点,最后中序遍历右子树【垂直映射法】后序遍历:先后序遍历左、右子树,然后访问根结点例:(1)先序遍历:
17、A.B.D.E.F.G.K.M.C.H.J 中序遍历:D.B.F.E.K.A.M.G.H.C.J P105 贴纸(1)后序遍历:D.F.K.M.A.E.B.H.J.C.G层次遍历:A.B.C.D.E.H.J.F.G.K.M例:(2)先序遍历:A.B.E.F.I.G.C.D.H.J.K.L.N.O.M后序遍历:E.I.F.G.B.C.J.K.N.O.L.M.H.D.A P105贴纸(2)层次遍历:A.B.C.D.E.F.G.H.I.J.K.L.M.N.O赫夫曼树遍历:例:W= 5,29,7,8,14,23,3,11 第六章 图图的定义:图(Graph):图G是由两个集合V(G)和E(G)组成的,
18、记为:G=(V,E)其中:V(G)是顶点的非空有限集;E(G)是边的有限集合,边是顶点的无序对或有序对。有向图,无向图顶点的度:无向图中,顶点的度为与每个顶点相连的边数;有向图中,顶点的度分成入度与出度入度:以该顶点为头的弧的数目出度:以该顶点为尾的弧的数目路径:路径是顶点的序列V=Vi0,Vi1,Vin,满足(Vij-1,Vij) E 或 E,(1r2.key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置重复
19、上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止。课件上的算法:void BubbleSort(int a, int n) int i, j, exchange; int tmp; for (i = 0; i i; j-) /比较,找出最小关键字的记录 if (aj 0)&(flag=1)flag=0;/flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序for(j=1;jL.rj+1.key)flag=1;/flag置为1,表示本趟排序发生了交换t=L.rj;L.rj=L.rj+1;L.rj+1=t;/交换前后两个记录/if-m;/while/BubbleSortC语言冒泡排序法:#includevoid main()int i,j,m, a10;printf(用冒泡排序法对a数组10个数组元素从小到大进行排序。n);printf(Enter the numbers:n);for(i=0;i10;i+)scanf(%d,&ai);for(i=0;i9;i+)for(j=0;j10-i;j+)if(aj+1aj)m=aj;aj=aj+1;aj+1=m;for(i=0;i10;i+)printf(%5d,ai);19