![2014考研计算机数据结构专项精讲课程讲义_第1页](http://file4.renrendoc.com/view/a3782ff3c695385482021b75a607a25e/a3782ff3c695385482021b75a607a25e1.gif)
![2014考研计算机数据结构专项精讲课程讲义_第2页](http://file4.renrendoc.com/view/a3782ff3c695385482021b75a607a25e/a3782ff3c695385482021b75a607a25e2.gif)
![2014考研计算机数据结构专项精讲课程讲义_第3页](http://file4.renrendoc.com/view/a3782ff3c695385482021b75a607a25e/a3782ff3c695385482021b75a607a25e3.gif)
![2014考研计算机数据结构专项精讲课程讲义_第4页](http://file4.renrendoc.com/view/a3782ff3c695385482021b75a607a25e/a3782ff3c695385482021b75a607a25e4.gif)
![2014考研计算机数据结构专项精讲课程讲义_第5页](http://file4.renrendoc.com/view/a3782ff3c695385482021b75a607a25e/a3782ff3c695385482021b75a607a25e5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
[ 绪 基本概 习 第一章线性 习 第二章栈、队列和数 队 数 习 第三章树与二叉 树的概 二叉 树和森 哈夫曼(Huffman)树和哈夫曼编 习 第四章 2[ 图的概 邻接 图的遍 习 第五章查 散列 习 第六章排 6.2排 冒泡排 希尔排 快速排 堆排 3[ 6.9基数排 习 4[[PAGEPAGE6
=(D,R,算法和算法的衡量T(n)n(输入量的多少,称之为问题规模)的某个函数T(n)=)增大,算法执行时间T(n)的增长率和f(n)的增长率相同。常见的渐进时间复杂度有:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<Ο(2n)<O(n!)<O(nn)间复杂度为O(1)。习 voidfn){intx=1;while} B. C. D.解答:A2、以下算法的时间复杂度是 voidf(intintp=1,d=n,f=n;while(d>0){if(d%2==1) f=f*f;d=d/2;}} B. C. D.whileifp=p*f语句可以不考虑,因为它执行的次数不超过d=d/2语句的执行次数。f=f*f2T(n)≤n,即T(n)≤log2n=O(log2n)。解答:A比较同一简单类型的两个数据x1和x2的大小,对于x1>x2,x1=x2和x1<x2这三种不同情 charcompare(SimpleTypex1,SimpleTypex2){[[if(x1>x2)elseif(x1==x2)return‘=’;elsereturn‘<’;}voidReverse(char{intfor(inti=0;i<n/2;{charch;}}从二维整型数 a[m][n]中查找出最大元素所在的行、列下标voidFind(inta[M][N],intm,intn,int&Lin,int {//MNM>=n和N>=n的条件,Lin和Col为形参,它是对应实参的别名,其值由实参带 for(intfor(intif}}voidfunc(int inty=while(y*yy}7[[线性表的定义
第一章性其中nn=0需要说明的是:ai为序号为 线性表的实现线性表的顺序结设a1的地址为Loc(a1),每个数据元素占d个地址,则第i个数据元素的地址为Loc(ai)=Loc(a1)+(i- #defineLIST_INIT_SIZE100 #defineLISTINCREMENT10 intInit_SqList(SqListL.elemElemType*malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!L.elem)exit(OVERFLOW); L.listsize= return}后使原表长为n的表:(a1,a2,...,ai-1,ai,ai+1,...,an)成为表长为n+1表:(a1,a2,...,ai-1,x,ai,ai+1,...,an)。ai~an顺序向下移动,为新元素让出位置;(注意数据的移动方向:从后往前依次x置入空出的第iif(i<1||i>L.length+1)return //位置不合if(L.length>=L.listsize)returnOVERFLOW;//当前空间已满,不q=&(L.elem[i- //q指示位for(p=&(L.elem[L.length-1]);p>=q;--*(p+1)= //位置及之后的元素右*q= // //表长增return}i(i1≤i≤n)个元素从线性表中去掉,删除后使原表长为n的线性表:(a1,a2,,ai-1,ai,ai+1,...,an)成为表长为n-1的线性表:(a1,a2,...,ai-1ai+1,...,an)。①将intDelete_SqList(SqList&L;inti)ifi1||i return //p&(L.elem[i- pe //被删除元素的值赋给qL.elem+L.length- //for(++p;p<=q;*(p-1)= //被删除元后的元素左-- //表长减return}素时,其后面的元素ai+1~an都要向上移动一个位置,共移动了n-i个元素,顺序表的、删除需移动大量元素O(n);但在尾端、删除效率高O(1)线性表的链式结单链的线性关系,对每个数据元素ai,除了存放数据元素的自身的信息ai之外,还需要和ai一起存放其后继ai+1所在的单元的地址,这两部分信息组成一个“结点”,结点的结构如图所typedefstruct //struct //LinkList L的地址放在了指针变量L、H中,头指针为“NULL”则表示一个空表。头插法——在链表的头部结点建立单链表 Crea(){LinkListL=NULL;LNodeintx; while(x!=flag) }}希望次序致,则入方法。为每次将结点链表的部,所需加入一个指针r用始终指链表中尾结点以便够新结点到链表尾部。不是结束标志时,申请结点,将新结点到r所指结点的后面,然后r指向新结点(注意 Crea(){LinkListL=NULL; intx; while(x!=flag) //r}if(r!=NULL) returnL;}“LL“”空表和” CreaistR2(){LinkListL=(LNode*)malloc(sizeof(LNode)); intx; while(x!=flag)r- //r}returnL;}查找操 * L, i); while(p->next!=NULL&&j<i){p=p->next;j++;}if(j==i)returnp;}运 pp×②①s在*p之后删除qq①p×②while(q- (1)单链表上、删除一个结点,必须知道其前驱结点[[(2)(2)循环链R来标识,可以使得操作效率双向链其后继结点的指针则为p->next,而找其前驱则只能从该链表的头指针开始,顺着各结点的nextO(1)O(n),如果也希望找前驱的时间性能达到O(1)typedefElemTypedata;structDuLNodep ②①④③s双向链表中结点的:设p指向双向链表中某结点,s指向待的值为x的新结点,将*s到*p的前面p ②①④③s[[①s->prior=p-②p->prior-③s-④p-否则*p的前驱结点的指针就丢掉了。×× ××① 双向链表中删除结顺序表和链表的比较O(n)(位置习1、循环链表的主要优点是(单链 D.顺序[[ 用()方式最节省运算时间。单链 B.仅有头指针的单循环链 D.仅有尾指针的单循环链D.删除地址为pD.将nq->prior=p;();A.q-B.q->prior->next=p;C.p->prior->next=p;7A=(a1,a2,am),B=(b1,b2,bn)均为顺序表,试编写一个比较A¸Bintcompare(SqListLa,SqListLb){{if(La.elem[i]==Lb.elem[i])i++;elseif(La.elem[i]<Lb.elem[i])elsereturn}if(i>La.length&&i>Lb.Length) if(i>Lb.Length) return1; return-}mink且小于maxkvoiddeleinkList&L,intmink,intwhile(p&&p- if(p)while(p&&p- //≥maxk //while{s=q- delete q=s;}//结点空}//}//voidinverse(LinkList&L)//逆置结点的单链表Lp=L->next;L->next=NULL;while(p){ p=}}voidunion(LinkList&Lc,LinkList&La,LinkList&Lb)//La和Lb归并为非递增的有序表Lc,归并之后,La和Lb//上述三个表均为结点的单链表,Lc表中的结点即为原La或Lb表中的结点Lc=new Lc->next=paLa pbLb //while(pa||pb) (!pa) {q=pb; pb=pb->next;}elseif (!pb) {q=pa; pa=pa->next;} if(pa->data<=pb->data){q= pa=pa->next; {q= pb=pb->next;q->next=Lc- Lc->next= //}dele dele //La和Lb的头结}//voidDifference_L(LinkList&La,LinkListLb,LinkListLc)LaLbLcLaLcpre=pa; while(pa&&pb&&pc){if(pa->data<pb-{pre=pa; pa=pa->next;}elseif(pb->data<pc->data)else deletepa;pa=pre-}//pbpc}//p=L->next;//L为双向链表的头指针while(p!=L&&p->data!=x) p=p->next;//搜索元素值为x的结点*pif(p==L) returnNULL;while(q!=L&&q->freq<p->freq) 将结点*p从当前位置上删除;之后将结点*p在结点*q之后;returnp;voidOneToThree(LinkedList&L,LinkedList&la,LinkedList&ld,LinkedList&{la=(LinkedList)malloc(sizeof(LNode)); r=L;L=L {r->next=la->next;la ∥处理字母字符。elseif(r->data>=‘0’&&r- {}}}第二章栈、队列和栈栈的定栈的实现和运算实 #defineSTACK_INIT_SIZE100 #defineSTACKINCREMENT10 需要注意,在栈的动态分配顺序结构中,base始终指向栈底元素,非空栈中的入栈:若栈不满,则将e栈顶intPush(SqStack&S,SElemType{if(S.top- *S.top return}SeOK,否则返回intPop(SqStack&S,SElemType ERROR;e=*--S.top;return}栈的应用举例N=(Ndivd)×d+Nmodd (其中:div为整除运算,mod为求余运算)例如:(1348)10=(2504)8,其运算过程如下: Ndiv Nmod N≠0Nrs(2);N=0s的内容依次出栈,NrN。voidconversion(){ //while(N){Push(S,N%8);N=N/8;}{printf("%d",e}}[[ 的算术运算符包括:+、*、/、%、^(乘方)和括号(。 +、 表达式作为一个满足表达式语则的串,如表达式“3*2^(4+*2-1*3)-”,它的3*2s1233#*32^^33#*32^^((4+2*2--1*#*^(-3#*^(-)(-#-5[[#96-5,91图中缀表达式3*2^(4+2*2-1*3)-5的求值过严格从左向右进行,而不用再考虑运算规则和级别。中缀表达式“3*2^(4+2*2-1*3)-5”的后 //本函数返回由后缀表达式A表示的表达式运 sch=*A++;InitStack(s);while(ch!=’#’){ Push(s,ch);else{Pop(s,&a); Pops&b)取出两个运算量switch(ch).{casech= c=a+b;breakcasech==’-’: c=a-b;break;casech==’*’:c=a*b;break;casech==’/’:c=a/b;break;casech==’%’:c=a%b;break;}Push(s,c)}ch=*A++}Pop(s,result); result;} 组A中,转换后的后缀表达式 在字符数组B中。具体做法:遇到运算对象顺序向 运算符出栈后不是进行相应的运算,而是将其送入B中存放。具体算法在此不再赘述。Acaoncr,这“递归工作栈”队队列的定义及基本运算入的一端叫队尾(rear),把允许删除的一端叫队头(front)。队列的实现及运算实#defineMAXQSIZE typedefstruct{ //动态分配空 } intEnQueue(Sueue&Q,QElemType{if((Q.rear+1)%MAXQSIZE==Q.front)returnERROR;Q.base[Q.rear]=e;return}{if(Q.front==Q.rear)returnERROR;e=Q.base[Q.front];Q.front=(Q.front+1)%MAXQSIZE;returnOK;}}typedefstructQNode{//QElemTypedata;structQNode}QNode,typedefstruct{ QueuePtrfront队头指针QueuePtrrear;//队尾指针} {QNode*)aoc(sieof(QNode);p->data=e;p->next=Q.rear->next=p;Q.rear=p;returnOK;}intDeQueue(LinkQueue&Q,QElemType&e)if(Q.front==Q.rear) p=Q.front->next;ep Q.rear=Q.front; free(p);return}特殊矩阵的压缩数一个数据元素有唯一的一组下标来标识,因此,在数组上不能做、删除数据元素的操作。元,那么aij的物理地址可用一线性寻址函数计算:LOC(aij)=LOC(a11)+((i-1)*n+j-1)*j-1LOC(aij)=LOC(a00)+(i*n+j)*d推广到一般的二维数组 [c2..d2],则aij的物理地址计算函数为LOC(aij)=LOC(ac1c2)+((i-c1)*(d2-c2+1)+(j-c2)特殊矩可以对其元素进行随机存取,各种矩阵运算也非常简单,并且的密度为1。但是在矩阵储是不太合适的,看起来密度仍为1,但实际上占用了许多单元去重复的非零元素线对称,因此只需上三角或下三角部分即可,比如,我们只下三角中的元素aij,其特点是中j≤i且1≤i≤n,对于上三角中的元素aij,它和对应的aji相等,因此当的元素在上三角时,直接去和它对应的下三角元素即可,这样,原来需要n*n个单元,现在只需要n(n+1)/2个单元了,节约了n(n-1)/2个单元。对下三角部分以行为主序顺序到一个向量中去,在下三角有n*(n+1)/2个元素,角中的某一个元素aij则具体对应一个sak,下面的问题是要找到ki、j之间的关系。 n(n+1)/2-……a1
第2 第3 第n对于下三角中的元素aij,其特点是:i≥j且1≤i≤n,到SA中后,根据原则,它前i-11+2+…+i-1=i*(i-1)/2aijj个,所以在上面的排列顺序中,aiji*(i-1)/2+j个元素,因此它在SA中的下标ki、j的关系为:k=i*(i-1)/2+j- (0≤k<n*(n+1)/2若i<j,则aij是上三角中的元素,因为aij=aji,这样,上三角中的元素aij时则去访ajiSA
k=j*(j-1)/2+i- (0≤k<n*(n+1)/2k=I*(I-1)/2+J-1SA[n*(n+1)+1]中,这种的方式可节约n*(n-1)-1个单元,sak与aji的对应关系为:i*(i-1)/2+j- ……ac1
项第2 第3 第n 项
i (np)p
=(i-1)*(2n-i+2)/2元素,而 (i-1)*(2n-i+2)/2+(j-i+1)SA中的下标为:k=(i-1)*(2n-i+2)/2+j-i。综上,sakaji的对应关系为:(i-1)*(2n-i+2)/2+j- ……a…c第1 第2
第n行常为零(或同一个常数c)。sakaji00000 000000 习1、若循环队列以数组Q[0..m-1]作为其结构,变量rear表示循环队列中的队尾元素的实rear=(rear+1Modmlength表示当前循环队列中的元素个数,则循环队列的队首元素的实际位置是().A.rear-B.(rear-length+m)ModmC.(1+rear+m-length)ModmA. B. C. D.intsymmetry(charCh[])//若Ch[]为称字符序列,则返回1,否则返回0。p=Ch;InitStack(S);while(*p!=‘&’){Push(S,*p);p++;}state=1;p++;//滤去字符‘&’while(*p!=‘@’&&state){{Pop(S,e);p++;elsestate=}Statusex() {//若从终端依次输入的字符序列“回文//则返回TRUE,否则返回FALSE while(ch!=@){Push(S,ch); EnQueue(Q,ch);}{{Pop(S); elsestate=FALSE;}return}[[ voiddemo1(sqstack&s){inti;arr[64];n=0;for(i=0;<n;i++)push(s,arr[i]);}voiddemo2(sqstack&s,intm){sqstackt;inti;while(!stackempty(s))while(!{i=pop(t);}}7、将一个A[1..100,1..100]的三对角矩阵,按行优先存入一维数组B[1‥298]中,A中元i=66,j=65A. B. C. D.A[k](0≦k﹤m*n)表示成矩阵的第i行、第j列的元素(0≦i﹤m,0≦j﹤n)。A.i=k/n, B.i=k/m,C.i=k/n, D.i=k/m,[[树T中:n>1m(m>0)T1,0的结点称为分支结点,或者称为非终端结点。一棵树的结点父结点(1≤i<k),n1,n2,…,nk称为一条由n1nk的路径。这条路径的长度是k-1。先,而N称为M的子孙。1二叉树定义与性质kn个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行,如果为i(1≤i≤n)的结点与满二叉树中为i的结点在二叉树中的位置相同,则性质 性质 x(1≤i≤kkM=
i- ∑2=2i- 性质 n0=n2+1 (1-3- 2性质 具有n个结点的完全二叉树的深度k为log2n+1或log2(n1)2k、结点个数为n时,有2k-1-1<n≤2k- k是整数,所k=log2n+15n个结点的完全二叉树,如果按照从上至下和从左到右的顺序对二叉树中的所有结点从1开始顺序,则对于任意的序号为i的结点,有:序号为i的结点无右孩子。此外,若对二叉树的根结点从0开始,则相应的i号结点的双亲结点的(i-1)/2,左孩子的 为2i+1,右孩子的 为2i+2。二叉树的成空间的大量浪费,不宜用顺序结构。的情况是右单支树,一棵深度为k的右单支树,只有k个结点,却需分配2k-1个单元。#defineMAX_TREE_SIZE100 typedefemTypeSqBiTree[MAX_TREE_SIZE]//0号单元存放根结点 //将b定义为含有MAX_TREE_SIZE个emType类型元素的一维数[[BiTNode{emTypedata;structBiTNode 其中,data、lchildrchild三个域的意义与二叉链表结构相同;parent域为指向该结二叉树的遍历{if [[PreOrder(b- //先序递归遍历b的右子}}{if //中序递归遍历b的左子树 //结点的数据域 //中序递归遍历b的右子树}}{ifPostOrder(b->lchild);//后序递归遍历b的左子树PostOrder(b->rchild);//后序递归遍历b的右子树 }}[[voidLevelOrder(BiTree{BiTreeQueue[MAX_TREE_SIZE];intwhile(front!=rear){Visit(Queue[++front]- if(Queue[front]->lchild!=NULL) Queue[++rear]=Queue[front]->lchild;if(Queue[front]->rchild!=NULL) Queue[++rear]=Queue[front]->rchild;}} //非递归先序遍历二[[inttop=0;{while(p!=NULL) else{} }if(top<=0)return; else{ //从栈出栈顶元 //指针指向p}}}只需将先序遍历的非递归算法中的Visit(p->data)移到p=Stacktop]和p=p->rchild线索二叉树n个结点的二叉树中的叶子结点和一个具有n个结点的二叉树若采用二叉链表结构,在2n个指针域中只有n-1个指针域是用来结点孩子的地址,而另外n+1个指针域存放的都是NULL。因此,可以利用用结点空的右指针域(rchild)该结点在某种遍历序列中的直接后继结点的地址;对通常为每个结点增设两个标志位域ltag和rtag,令: { {rtag= typedefstructBiThrNode{ structBiThrNode 实质上就是遍历一棵二叉树。在遍历过程中,Visit操作是检查当前结点的左、右指针域针pre始终指向刚刚过的结点,即若指针p指向当前结点,则pre指向它的前驱,以便增if(!(head=(BiThrNode*)malloc(sizeof(BiThrNode)))) if(!T)head->lchild=head; pre=head; }return}p){if(p){InThreading(p- //左子树if(!p->lchild){ p-}if(!pre->rchild){ } }}②如果该结点的左标志为0,表明该结点有左孩子,根据中序遍历的定义,它的前驱结当某结点的右标志为1时,它就是所要找的前驱结点。{BiThrTreepre;if(p-}②如果该结点的右标志为0,表明该结点有右孩子,根据中序遍历的定义,它的前驱结当某结点的左标志为1时,它就是所要找的后继结点。{BiThrTreepost;if(p-}树的结#define 100//typedefstruct #defineMAXNODE100 typedefstructChildNode{intstructChildNode}typedefstruct structChildNode* {emTypedata;structTreeNode*son;structTreeNode 森林和二叉树的转换这样,对树的操作实现就可以借助二叉树,利用二叉树上的操作来实现。(详见PPT)树和森林的遍历哈夫曼(Huffman)树和哈夫曼编码点都具有一定的权值,则可将这一概念加以推广。设二叉树具有n个带权值的叶结点,那么 WPL=∑Wk·L(afan(即哈夫曼树)WL小结远结哈曼(afan依一提法种方n个权值{W1,W2,…,Wn}n棵只有一个叶结点的二叉树,从而得到一个二叉树的集合F={T1,T2,…,Tn};F中选取根结点的权值最小和次小的两棵二叉树作为左、右子树构造一棵新的二叉树,(2(3)于一个字符的哈夫曼编码是从根结点到相应叶结点所经过的路径上各分支所组成的0,1序习 A. C. D.后序遍历序列中x在y之后,则x和y的关系是(。A.x是y的左兄 B.x是y的右兄 D.x是y的后 A.n在m的右 B.n是m的祖C.n在m的左 D.n是m的子a:b:c:d:e:f:g:=== node*fch,*nsib;intLeaves(Tree if(t=null)return }第四章VRADTGraph数据关系R:VR={<v,w>|v,w∈VP(v,w),<v,w>v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}无向图:在一个图中,如果任意两个顶点构成的偶对(v,w)∈E是无序的,即顶有向图:在一个图中,如果任意两个顶点构成的偶对(v,w)∈E是有序的,即顶为无向完全图。在一个含有n个顶点的无向完全图中,有n(n-1)/2条边。连接,则称该图为有向完全图。在一个含有n个顶点的有向完全图中,有n(n-1)条边。数目,记为ID(v)vv为始点的弧的数目,记为OD(v)。TDv)=IDv)+ODv)n(weight某种含义。边上带权的图称为网图或网络(network。如果边是有方向的带权图,则就是一vim,vq。其中(vp,vi1,(vi1,v2),…,(vim,.vq)分别为图中的边。G=(V,E,G’=(V’,E’集,则称图G’是G的一个子图。vivj是连通的。如果图中任意两顶点都是连通的,则称该图是连通图。无向图的vivj(i≠j)均有vivjvjvi的路径,则称该有向图是强连通图。有GGn个顶点的一个极小连通Gn-1条边。在生成树中添加任意一条属于原图中的边必定会图的及基本操邻接矩系为一个n×n的矩阵,矩阵的元素为:
若(vi,vj)或<vi,vj>是E(G)中的{ 若(v,v)或<v,v>不是E(G)中的{i i
若(vi,vj)或<vi,vj>是E(G)中的边0或∞若(v,v)或<v,v>E(G)中的边{i i{其中,wij表示边(vi,vj)或<vi,vj>上的权值;∞表示一个计算机允许的、大于所有边上权值i行(i列)非零元素(或非∞元素)的个数正好是第i个顶点的度TD(vi)。i行(i列)非零元素(或非∞元素)的个数正好i个顶点的出度OD(vi)(ID(vi。 #defineMAX_VERTEX_NUM20 //最大顶点数设为20typedefcharVertexType; typedefintVRType; typedefstruct{ //顶点VRTypeedges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵,即边表 //MGragh是邻接矩阵的图类邻接邻接表(AdjacencyList)是图的一种顺序与链式结合的方法。邻接表表示法类似于树的孩子链表表示法。就是对于图G中的每个顶点vi,将所有邻接于vi的顶点vj链成vi的邻接表,再将所有点的邻接表表头放到数组中,就 邻接点 边(info#define ode typedefstruct *}VNode,AdjList[MAX_VERTEX_NUM];//AdjList是邻接表typedef //ALGraph是以邻接表方式的图类型n个顶点、en2e个表结点。显而在有向图中,第i个链表中的结点个数只是顶点vi的出度,为求入度,必须遍历整个邻接表。在所有链表中其邻接点域的值为i的结点的个数是顶点vi的入度。对每个顶点vi建立一个以vi为头的弧的链表。O(n+e·e顶点(vi和vj)ij个链表,因此,不及邻接矩阵深度优先搜索假设初始状态是图中所有顶点未曾被则深度优先搜索可从图中某个顶点发v 此顶点,然后依次从v的未被的邻接点出发深度优先遍历图,直至图中所有和v有问标志数组visited[0:n-1],,其初值为FALSE,一旦某个顶点被,则其相应的分量置为voidDFSTraverse(GraphG){ for(v=0;v<G.vexnum;++v)visited[v]= for(v=0;v<G.vexnum; }voidDFS(GraphG,intv){ //从第v个顶点出发递归地深度优先遍历图G //第v个顶点for(w=FisrtAdjVex(G,v);w>=0; }图的结构时,查找每个顶点的邻接点所需时间为O(n2),其中n为图中顶点数。而当以邻接表作图的结构时,找邻接点所需时间为O(e),其中e为无向图中边的数或有向图中弧的数。由此,当以邻接表作结构时,深度优先搜索遍历图的时间复杂度为O(n+e)。广度优先搜索假设从图中某顶点v出发,在了v之后依次v的各个未曾过和邻接点,然中所有顶点都被到为止。换句话说,广度优先搜索遍历图的过程中以v为起始点,由近至远,依次和v有路径相通且路径长度为1,2,…的顶点。voidBFSTraverse(GraphG){ for(v=0;v<G.vexnum;++v)visited[v]= for(v=0;v<G.vexnum;if }voidBFS(GraphG,intv) visited[v]=TRUE;Visit(v); //v //v入队列 //uif(!visited[w]){ //u尚 }}}图的基本应用最小生成树n个顶点的无向连通图,无论其生成树的形态如何,所有生成树中都有且仅有n-1条边。假设G=(V,E)为一网图,其中V为网图中所有顶点的集合,E为网图中所有带权边的集合。设置两个新的UT,其中U用于存G的最小生T存放G的最小生成树中的边。令集合U的初值为U={u1}(假设构造最小生成树时,从顶点u1出发T的初值为T={}。uvv加入U中,将边(u,v)T中,如此不断重复,直到U=V时,最小生成树构造完毕,这时集合T中包含了最小生成树的所有边。while(u,v)=min{wuv;u∈U,v∈V-U}T=T+{(u,Kruskal算法是一种按照网中边的权值递增的顺序构造最小生成树的方法。其基本思想是:设无向连通网G=(V,E)G的最小生成树为T,其初态为T=(V,{},即开[[构成通分量。然后,按照边的权值由小到大的顺序,G的边E中的各条边。若被的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为通分量;若被边的两个顶点属于同通分T1时,此连通分量便为G的一棵最小生成树。最短路V长度最短者。其中,从源点到顶点vV例迪杰斯特拉(Dijkstra)算ST=V-SS中存放已找到最短路[[个新的顶点u,都要修改顶点v0到集合T中剩余顶点的最短路径长度值,集合T中各顶点新uu到该顶点的路径长度值中的较小值。此过程不断重复,直到集合T的顶点全部加入到S中为止。Dijkstrax,那么,(v0,xxS中,那么必然存在另外的终点S中而路径长度比此路径还短的路径,这与我们按路径长度递增的顺序产生最短路径的vivviD[i]D[i],vjvk,则可想而知,是D[j]和从vj到vk的弧上的权值之和。D[j]=Min{D[i]|vi∈V-其中,D[i或者弧(v,vi)D[kvk∈S和弧(vkvi)上的权值之和。若〈vi,vjedges[i][j]为∞(在计算机上可用允许的最大值代替。S为已找到从v出发的最短路径的终点的集合,它的初始状态为空集。那么,从v出发到图上其余各顶点D[i]=edges[LocateVex(G,v)][i]②选择vj,使D[j]=Min{D[i]|vi∈V-则修改D[k]这样,便可求得每一结顶点的最短路径。总的执行时间 O(n3),,(即判别弧(vi,v0)和(v0,vj)是否存在。如果存在,则比较(vi,vj)和(vi,v0,vj)的路径长vivj0的最短路径。假如在路径上再增加v1(viv1)和(v1vj)分别是当前找到的中间顶点的序号0的最短路径,那么(viv1vj)vivj的中间顶点的序号不大于1vivj0的最短路径相比较,从中1v2,继续进行试探。依次类推。在一般情况下,若(vivk)和(vkvj)vivkvkvj的中间顶点的k-1的最短路径,则将(vivkvj)vivj且中间顶点序号k-1vivjk的最D(-1),D(0),D(1),…,D(k),D(n-D(-D(k)[i][j]=Min{D(k-1)[i][j],D(k-1)[i][k]+D(k- 0≦k≦n-Dk)[i][j]vivj的中间顶点的个数不大于k的最短路径的长度;Dn-1)[i][j]vi到vj的最短路径的长度。拓扑排AOV的有向图称AOV网。在AOV网中i到顶j之间存在一条有向路径ijji的后继。若<i,j>ij的直接前驱,顶点j是顶点i的直接后驱。AOV网所代表的一项工程中活动的集合显然是一个偏序集合。为了保证该项工程得以AOV网是否具有回路(即是否是一个有向无环图)的方法,就是在AOV网的偏序①在AOV网中,若顶点i优先于顶点j, i优先于顶点jji。若某AOV网中所有顶点都在它的拓扑序列中,则说明该AOV网不会存在回路,这时O(e+n关键路AOE销(如该活动持续的时间,则此带权的有向图称为AOE网。AOEvk的所有活动<vj,vk>都结束时,vk代表的事件才能发生;而活动<vj,vk>ve[j]+dut(<vj,[[(<, <vj (1-4-发的所有活动<vk,vj>的终点vj的最迟时间vl[j]。vl[k]的计算方法如下:(< vk (1-4-始。也就是说,活动ai的最早开始时间应等于事件vk的最早发生时间。因此,有: 由弧vk,vj>>aivj的最迟发生时间不拖后。因此,应该 l[i]=e[i]l[i]>e[i]的活动则不是关键活动,l[i]-e[i]的如果得到的拓扑有序序列中顶点个数小于网中顶点数n,则说明网中存在环,不能求关键路vnvl[n-1]=ve[n-1],按逆拓扑有序求其余各顶点的最迟发生时间若某条弧满足条件e(s)=l(s),则为关键活动。习接矩阵为A[1…n,1…n],且压缩在B[1…k],则k的值至少为(。 B.C.(n- D.n(n-[[2n个结点、k条边的非连通无向图是一个森林(n>k,则该森林中必有() B. C.n- D.3G36条边的非连通无向图(不含自回路和多重边G至少有() B. C. D.通,则n=10。 【分析】当有向图中无回路时,从某顶点出发进行深度优先遍历时,出栈的顺序(DFSTraverse算法)即为逆向的拓第五章查找的基本概念nASLP1C1P2C2 Pii个数据元素的概率,Cii个数据元素时,已经typedefstruct}//某个记录的关键字值与给定值相等,则查找成功,返回该记录的位置,反之,若直到 struct //}Sem[0].key=key; //设置“哨兵” //从后往前return //找不到时,i}nPi(n-1Pin nASL=∑─(n-i+1)=i=1 度,其为O(n)。intSearch_Bin(SSTableST,KeyTypekey)low high //while(low<=high)mid=(low+high)/if(key==S mid;//找到待查元 if(key<Sem[mid].key)high=mid- //继 lowmid //}return //}nk,则2k-1-1<n≤2k-1,即k-1<log2(n+1)≤k,所k=log2(n+1)。因此,折半查找在查找所进行的关键码比较次数至多为log2(n+1)nnnASL=∑— —n=n+1log(n+1)-1≈log(n+1)- n所以,折半查找的时间效率为O(log2n)动态查找树表二叉排序树 if(!breturn elseif(b->data.key==key)returnb; elseif(key<b->data.key)returnSearchBST(b->lchild,key); }在二叉排序树中一个结点的过程:设待结点的关键码为key,为将其,先voidInsertBST(BiTree {BiTreeif(bt==NULL){//递归结束条件s->data.key=key;} elseif(key>b-> }intDeleteBST(BiTree KeyTypekey)if return //keyelseif(LT(key,b->data.key))DeleteBST(b->lchild,key); DeleteBST(b->rchild,key);}}voidDelete(BiTree&p//ifp->rchild //q=}elseifp->lchild //q=p=p->rchild;}else //q=s=p-while(!s->rchild){ q=s;s=s-}p->datas if(q!=p)q->rchild=s->lchild;//重接*q的右子树elseq->lchild=s->lchild; //重接*q的左子树}}n个关键字,构造所得的不同形态的各棵二叉排序树的平均查找长度的由关键字序列1,2,3,4,5构造而得的二叉排序树,ASL=(1+2+3+4+5)/5=3。3,1,2,5,4构造而得的二叉排序树,ASL(1+2+3+2+3)52.2。平衡二叉树[[在平衡二叉树上或删除结点后,可能使树失去平衡,因此,需要对失去平衡的树进a结点为失去平衡的最小子树根结点,对该子树进行平衡化调整归纳起来--ac0EDB --ac0EDBxExEBDBDa xExEBDBDah
图RR型结点a的平衡因子绝对值大于1,以结点a为根的子树失去平衡。cDaaB,右Dacc为新的根结点,如图(c)。平衡化调整操作判定:沿路径检查三个点a、c、E,若它们处于“\”直线上的同一个一个方向,则要作右单旋转,即以结点c为轴顺时针旋转,如图所示。2a12a1cBaB0BxDExDEDE DE
cxEaxEBDBD a.
LLb的右子树上,并使结点b的右子树高度增1,从而使结点a的平衡因子的绝对值大1a0bc0hhG1a0bc0hhGF1DEhLR型22ac0hDG22ac0hDGE2a-1c1GDEFhExFxF xFxFh- h0c0a-h-GxD0c0a-h-GxD1a11a1hh-xFDGE2a-1c-h-hxGFDEc xGEFDhxGEFD h-h h LR直线上的同一个方向,则要作右单旋转,即以结点c为轴顺时针旋转,如图(c、f)。的关键码个数不超过树的深度。在平衡树上进行查找的时间复杂度为O(logn)。[[ 树及其基本操作、B+树的基本概念,,,,键码均大于Kn,m/21≤n≤m1,n为关键码的个数。B-树的查找类似二叉排序树的查找,所不同的是B-树每个结点上是多关键码的有序表,在到达某个结点时,先在有序表中查找,若找到,则查找成功;否则,到按照对应的指针信息指向的子树中去查找,当到达叶子结点时,则说明树中没有对应的关键码,查找失败。即在B-树上的查找过程是一个顺指针查找结点和在结点中查找关键码交叉进行的过程。B-树的查找是由两个基本操作交叉进行的过程,即①在B-树上找结点;②在结点中找关码由于通常B-树是在外存上的,操作①就是通过指针在磁盘相对定位,将结点信息读入内存,之后,再对结点中的关键码有序表进行顺序查找或折半查找。因为,在磁盘上读取结点信息比在内存中进行关键码查找耗时多,所以,在磁盘上结点信息的次数,即B-B-树查找效率的首要因素。那么,对含有n个关键码的m阶B-树,情况下达到多深呢?可按二叉平衡树进行类似分析。首先,m阶B-数各层上的最少结点数。B-12个结点;由于除根结点外的每个非终端结点至少有m22(m2)个结点;……;以树有n个关键码,则叶子结点即查找不成功的结点为n+1,由此有:nn+1≥2*(m/2n即klogm2
12n上涉及的结点数不超过logm/2
2⑴有nn;值≤Ki,则应继续在Ai所指子树中进行查找。B+树查找的分析类似于B-树。散列表散列表与散列方法keykey与地址单元中元素关键码进行比n个数据元素的集合,总能找到关键码与存放地址一一对应的函数。若最大关键为m,可以分配m个数据元素存放单元,选取函数f(key)=key即可,但这样会造成空间的常用的散列函数H(key) 或者H(key)akey 此法仅适合于:地址集合的大小==关键字集合的大小s位数字组成(k1,k2,kn),分析关键字集中的H(key)keyMOD p≤m表长pp很重要,若散列表表长为m,则要求p≤m,且接近m或等于m。p一般选取质数,也可以是不包含小20H(key)=Random(key),其中,Random为伪随机函数。处理的方 (1≤i<mHash(key)为散列函数,m为散列表长度,di1,2,……,m-1,且[[线性探测法可能使第i个散列地址的同义词存入第i+1个散列地址,这样本应存入第i+1个散列地址的元素变成了第i+2个散列地址的同义词,……,因此,可能出现很多元素在相邻d12,-12,22,-22,……,q2,-q2q≤1mi2(行。链地址法适用于经常进行和删除的情况。散列表的查找对于给定值K,计算散列地址i=H(K),r[iNULL,则查找不成功若r[i].key=K,则查找成功否则求下一地址Hi,直至r[Hi]= 或r[Hi].key= 散列表的查找分析介绍的处理的方法中,产生后的查找仍然是给定值与关键码进行比较的过程。所以,[[散列表的装填因子定义为:α=────────────α是散列表装满程度的标志因子。由于表长是定值,α与“填入表中的元素个数”成正比,所以,α越大,填入表中的元素较多,产生的可能性就越大;α越小,填入表中的元素较1(11(1 1 1U1(1 (11ln(1 12Unc)习以后,要查找元素30要进行( B. D. A.27 D.4、在常用的描述二叉排序树的结构中,关键字值最大的结点(左指针一定为空B.C.左右指针均为空D.5、设顺序的某线性表共有123个元素,按分块查找的要求等分为3块。若对索引表采用分块查找成功的平均查找长度为(。[[ B. C. D.平均查找长度为23。 D.散列的平均探查次数不超过1.5,则散列表项应能够至少容纳()个表项。 8n2n的递增有序表,最少需要进行关键字比较()次。 突。假设装填因子α=0.75,散列函数的形式为H(K)=KMODP,回答下列问题:解答:由α=0.75,得表长m=11/0.75=15.[[排序的基本概念
第六章n个记录的序列{R1,R2,…,Rn},其相应关键字的序列是{K1,K2,…,Kn},相应p2,…,pn,使得相应关键字满足如下的非递减(或非递增)关系,即:Kp1≤Kp2≤…≤Kpn,实现排序的基本操作有两个:(1)“比较”序列中两个关键字的大小;(2)“移动”记录。排直接排直接排序是最简单的类排序。仅有一个记录的表总是有序的,因此,对n个记录的表,可从第二个记录开始直到第n个记录,逐个向有序表中进行操作,从而得到n个记录按关键码有序的表。它是利用顺序查找实现“在R[1..i-1]中查找R[i]的位置”的R[0]=R[i]; //设置“哨兵”-- //return //返回R[i]的位置为for(j=i-1;R[0].key<R[j].key;--j);R[j+1]=R[j](3)i2,3,n,voidInsertionSort(ElemR[ {for(i=2;i<=n;++i)R[0] [[for(j=i-1;R[0].key< --jR[j+1] //R[j+1]= //到正确位}}空间效率:仅用了一个辅助单元,空间复杂度 O(1)直接排序的最好情况的时间复杂度为O(n),平均时间复杂度为O(n2)折半排直接排序的基本操作是向有序表中一个记录,位置的确定通过对有序表中记录按关键码逐个比较得到的。平均情况下总比较次数约为n2/4。既然是在有序表中确定插入位置,可以不断二分有序表来确定位置,即一次比较,通过待记录与有序表居中一分为二。这样继续下去,直到要比较的子表中只有一个记录时,比较一次便确定了位R[n-R[n-无序序列无序序列R[1..n-则第i趟起泡 序序列中关键字最大的记录“交换”到R[n-i+1]的位置上。voidBubbleSoremR[],inti iwhile(i>1)lastExchangeIndex=1;for(j=1;j<i;j++) lastExchangeIndex=}i=}}空间效率:仅用了一个辅助单元,空间复杂度为O(1)时间效率:最好情况的时间复杂度为O(n),平均时间复杂度为O(n2)。 2总比较次数(j1) n(n2j简单选择排序i趟简单选择排序是,从无序序列R[i..n]的n-i+1记录中选出关键字最小的记录加入有序序列。n1个记录交换;第二趟,n-12i趟,则从第i个记录开始的n-i+1个记录中选出关键码最小的记录与第i个记录交换,直到整voidSelectSort(ElemR[],intn){ //对记录序列R[1..n]作简单选择排序。for(i=1;i<n;++i){ //选择第i小的记录,并交换到位kSelectMinKey(R R[i..n]keyifi!=j //i}}【性能分析空间效率:仅用了一个辅助单元,空间复杂度为O(1)时间效率:简单选择排序的最好和平均时间复杂度均 O(n2)稳定性:不同对简单选择排序的稳定性有争议,一般认为,若是从前往后比较来选择第ii小的记录则该算法是不稳 [[nn到(n)。希尔排即是从这点出发给出排序的改“较稀疏的”,离1在个排记为d1的分组行直序后两录d2<1为d2,=1空间效率:仅用了一个辅助单元,空间复杂度 O(1)子序列的选取,特定情况下可以准确估算出关键码的比较次数和记录的移动次数。目前还没有人给出选取最好的步长因子序列的方法。步长因子序列可以有各种取法,有取奇数的,也11。intPartition1(ElemR[],intlow,inthigh)pivotkey //( //while(low<high&&-- //while(low<high&& //}return //}枢轴记录“移出”,待求得枢轴记录应在的位置之后(此时low=high),再将枢轴记录到位。intPartition2(ElemR[],intlow,inthigh)R[0] //pivotkey //( //-- //while(low<high&&R[high] //}R[low //return //}voidQSort(ElemR[],intlow,inthigh)//iflowhigh-1 //pivotloc=Partition(L,low,high);//将L.r[low..high]一分为二QSort(L,low,pivotloc-1);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 文山2025年云南文山市公安局第一批警务辅助人员招聘47人笔试历年参考题库附带答案详解
- 怒江2025年云南怒江州财政局公益性岗位招聘笔试历年参考题库附带答案详解
- 广州2024年广东广州市海珠区江海街道基层公共就业创业服务岗位招募笔试历年参考题库附带答案详解
- 2025年纳豆香菇丝项目可行性研究报告
- 2025年电动桥式圆角挡闸项目可行性研究报告
- 2025至2031年中国洁净吹淋传递窗行业投资前景及策略咨询研究报告
- 2025至2031年中国朱雀系列外墙砖行业投资前景及策略咨询研究报告
- 2025年插件式铝基板项目可行性研究报告
- 2025年定柱悬臂起重机项目可行性研究报告
- 2025至2031年中国保尔塑像行业投资前景及策略咨询研究报告
- 2023-2024学年九年级三调语文试卷(含答案)
- 医学教程 常见急腹症的超声诊断课件
- DB11T 1481-2024生产经营单位生产安全事故应急预案评审规范
- 《氓》教学设计 2023-2024学年统编版高中语文选择性必修下册
- 《网店运营与管理》第3版 课件全套 白东蕊 第1-11章 网上开店概述- 移动网店运营
- 2024年全国国家电网招聘之电网计算机考试历年考试题(附答案)
- 化学元素周期表注音版
- 药物过敏性休克
- T-GDASE 0042-2024 固定式液压升降装置安全技术规范
- 2024福建省厦门市总工会拟录用人员笔试历年典型考题及考点剖析附答案带详解
- 四川省康定市大槽门金矿资源储量核实报告
评论
0/150
提交评论