A—熟练掌握 B—理解 C—了解
第一章:绪论
为merge()所需的时间,设为cn(c为常量)。因此
令 ,有
有
第二章:线性表
1.线性表的基本运算:…… C
2.线性表的顺序存储(利用静态数组或动态内存分配)。 相应的表示与操作 A
3.线性表的链式存储。相应的表示与操作。包括循环链表、双向链表。 A
4.顺序存储与链式存储的比较:基于时间的考虑–分别适用于静态的和动态的操作:比如静态查找和插入删除);基于空间的考虑-- ……. B
这也适用于后面用两种方式存储的其他数据结构。
★本章重点:很熟悉顺序表,单链表、双链表,循环链表的基本操作;并学会在各种链表上进行一些算法设计(与基本操作类似的操作或组合),请仔细复习。
例4.假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
[题目分析]因为两链表已按元素值递增次序排列,将其合并时,均从第一个结点起进行比较,将小的链入链表中,同时后移链表工作指针。该问题要求结果链表按元素值递减次序排列。故在合并的同时,将链表结点逆置。
void Union(LinkList la, LinkList lb)
∥la,lb分别是带头结点的两个单链表的头指针,链表中的元素值按递增序排列,本算法将两链表合并成一个按元素值递减次序排列的单链表。
{ pa=la->next; pb=lb->next;∥pa,pb分别是链表la和lb的工作指针
la->next=null; ∥la作结果链表的头指针,先将结果链表初始化为空。
while(pa!=null && pb!=null) ∥当两链表未访问结束
if(pa->data<=pb->data)
{ q=pa->next; ∥将pa 的后继结点暂存于q。
pa->next=la->next; ∥将pa结点链于结果表中,同时逆置。
la->next=pa;
pa=q; ∥恢复pa为当前待比较结点。
}
else{
q=pb->next;∥ 将pb 的后继结点暂存于q。
pb->next=la->next; ∥将pb结点链于结果表中,同时逆置。
la->next=pb;
pb=q; ∥恢复pb为当前待比较结点。
}
while(pa!=null) ∥将la表的剩余部分链入结果表,并逆置。
{q=pa->next; pa->next=la->next; la->next=pa; pa=q; }
while(pb!=null)
{q =pb->next; pb->next=la->next; la->next=pb; pb=q; }
}∥算法Union结束。
注意:
(1)此处q用作暂存后继结点,操作后pa或pb还回原指向位置;这与我们原来不改变pa或pb的指向,增加一个q=pa或pb作为摘取结点进行添加操作起到的作用一样。
(2) 此处要完成逆序插入操作故用头插法(基于头指针la或lb),注意尾插法(附设一个尾指针,基于该指针插入)的可完成顺序插入。(注意:逆序另一种方式也要掌握!)
练习:
练习题2 编程1——6
7.判断带头结点双向循环链表L是否对称相等.
8. 设计一个算法判断单链表(带头结点)是否是递增的(注意比排序算法应该简单,链表排序也要会实现)
9. 设计一个算法判断有序表A是否是有序表B的子集(即表A中的元素在B中)。(思考:如果递归程序怎么写?)
第三章:栈与队列
1.两种特殊线性表:分别有后进先出、先进先出的特性。 B
2.栈的顺序表示与实现(利用静态数组或动态内存分配) A
注意栈顶指针的初始位置不同,进出栈,栈空栈满的实现语句有差别!
举例:
若定义
typedef struct {
SElemType *base;
SElemType top;
int stacksize;//当前栈能使用的最大容量
} SqStack;
SqStack s;
top的初始值指向栈底,即top=base;
栈空条件:s. top ==s. base 此时不能出栈
栈满条件:s.top-s.base>=s.stacksize
进栈操作:s.top++=e; 或s.top=e; s.top++;
退栈操作:e=–s.top; 或s.top–; e=*s.top
若定义:
typedef struct {
SElemType base[MAXSIZE];
int top;
}SqStack;
SqStack s;
top的初始值为0时:
栈空条件:s. top ==0 此时不能出栈
栈满条件:s.top >= MAXSIZE
进栈操作:s.base[s.top++]=e;
退栈操作:e=s.base[–s.top]
top的初始值为-1时:
栈空条件:s. top == -1 此时不能出栈
栈满条件:s.top >= MAXSIZE-1
进栈操作:s.base[++s.top]=e;
退栈操作:e=s.base[s.top–]
3.栈的链式表示与实现 B (对比顺序栈,实质不带头结点的链表在头指针处插入和删除)
4.队列的顺序表示与实现—循环队列 A
设两个指针:Q.front 指向队列头元素;Q.rear 指向队列尾元素的下一个位置
注意队中若Q.rear 指向队列尾元素,进出队,实现语句有差别!
初始状态(空队列):Q.front = Q.rear=0
队头指针进1: Q.front = (Q.front + 1)% MAXSIZE
队尾指针进1: Q.rear = (Q.rear + 1)% MAXSIZE;
队列初始化: Q.front = Q.rear = 0;
队空条件: Q.front == Q.rear;
队满条件:(Q.rear + 1) % MAXSIZE == Q.front
队列长度:(Q.rear-Q.front+MAXSIZE)%MAXSIZE
6.队列的链式表示与实现 B
本章重点:顺序栈的初始条件、操作,循环队列的初始条件、操作
本章难点:栈的设计与使用,队列的设计与使用(主要结合后面树和图中的应用复习)
例5.链栈与顺序栈比起来优势在于 。
没有预设容量的限制
例6.计算算术表达式的值时,可用两个栈作辅助工具。对于给出的一个表达式,从左向右扫描它的字符,并将操作数放入栈S1中,运算符放入栈S2中,但每次扫描到运算符时,要把它同S2的栈顶运算符进行优先级比较,当扫描到的运算符的优先级不高于栈顶运算符的优先级时,取出栈S1的栈顶和次栈顶的两个元素,以及栈S2的栈顶运算符进行运算将结果放入栈S1中(得到的结果依次用T1、T2等表示)。为方便比较,假设栈S2的初始栈顶为®(®运算符的优先级低于加、减、乘、除中任何一种运算)。现假设要计算表达式: A-BC/D+E/F。写出栈S1和S2的变化过程。
步骤 栈S1 栈S2 输入的算术表达式(按字符读入)
初始 ® A-BC/D+E/F®
1 A ® A-BC/D+E/F®
2 A ®- -BC/D+E/F®
3 AB ®- BC/D+E/F®
4 AB ®- C/D+E/F®
5 ABC ®- C/D+E/F®
6 AT1(注:T1=B*C) ®-/ /D+E/F®
7 AT1D ®-/ D+E/F®
8 AT2(注:T2=T1/D)
T3 (注:T3=A-T2) ®-
®+ +E/F®
9 T3E ®+ E/F®
10 T3E ®+/ /F®
11 T3EF ®+/ F®
12 T3T4(注:T4=E/F)
T5(注:T5= T3+ T4) ®+
® ®
例7.将两个栈存入数组V[1…m]应如何安排最好?这时栈空、栈满的条件是什么?,入栈和出栈的操作是什么?
分析:为了增加内存空间的利用率和减少溢出的可能性,由两个栈共享一片连续的空间时,应将两栈的栈底分别设在内存空间的两端,这样只有当两栈顶指针相邻(即值之差的绝对值为1时才产生溢出。
设栈S1和栈S2共享向量V[1…m],初始时,栈S1的栈顶指针top0=0,栈S2的栈顶指针top1=m+1,当top0=0为栈S1空,top1=m+1为栈S2空;当top0=0并且top1=m+1时为两栈全空。当top1-top0=1时为栈满。
入栈核心操作 S1: V[++top0]=x1; S2: V[–top1]=x2
出栈核心操作 S1: x1=V[top0–]; S2: x2=V[top1++]
例8.如果用一个循环数组base[0…MAX-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,而改置计数器count用以记录队列中结点的个数。
(1)编写实现队列的三个基本运算:判空、入队、出队
(2)队列中能容纳元素的最多个数是多少
typedef struct
{ ElemType base[MAX];
int front,count; //front是指向队头元素针,count是队列中元素个数。
}CQueue; //定义类型标识符。
(1)判空:int Empty(CQueue q) //q是CQueue类型的变量
{if(q.count0) return(1);
else return(0); //空队列
}
入队: int EnQueue(CQueue q,ElemType x)
{if(q.countMAX){printf(“队满\n”);exit(0); }
q.base[(q.front+q.count)%MAX]=x; //x入队
q.count++; return(1); //队列中元素个数增加1,入队成功。
}
出队: int DelQueue(CQueue q, ElemType &x)
{if (q.count==0){printf(“队空\n”);return(0);}
x=q.base[q.front];
q.front=(q.front+1)%MAX; //计算新的队头指针
q.count–;
return(1);
}
(2) 队列中能容纳的元素的个数为MAX。
第四章:串
1.串的基本概念 C
2.串的顺序表示与实现(两种存储方式) A 特别的模式匹配算法之KMP算法 B
本章重点:串的定长顺序存储和堆分配存储、掌握一些常规的串操作(自己会用和会编写)
本章难点:串的模式匹配快速算法(KMP)
例9. 串的定长顺序存储缺点在于存在 情况。
截断
例10.已知u=‘xyxyxyxxyxy’;t=‘xxy’;
ASSIGN(s,u);
ASSIGN(v,SUBSTR(s,INDEX(s,t),LEN(t)+1));
ASSIGN(m,‘ww’)
求REPLACE(s,v,m)= ________。
‘xyxyxywwy’
例11.14.设字符串S=‘aabaabaabaac’,P=‘aabaac’
(1)给出S和P的next值和nextval值;
(2)若S作主串,P作模式串,试给出利用BF算法和KMP算法的匹配过程。
.(1)(1)p的next与nextval值分别为012123和002003。
(2)利用BF算法的匹配过程:
第一趟匹配: aabaabaabaac
aabaac(i=6,j=6)
第二趟匹配: aabaabaabaac
aa(i=3,j=2)
第三趟匹配: aabaabaabaac
a(i=3,j=1)
第四趟匹配: aabaabaabaac
aabaac(i=9,j=6)
第五趟匹配: aabaabaabaac
aa(i=6,j=2)
第六趟匹配: aabaabaabaac
a(i=6,j=1)
第七趟匹配: aabaabaabaac
利用KMP算法的匹配过程:
第一趟匹配:aabaabaabaac
aabaac(i=6,j=6,nextval(j)=3)
第二趟匹配:aabaabaabaac
(aa)baac (i=9,j=6)
第三趟匹配:aabaabaabaac
(成功) (aa)baac(i=13,j=7)
例12.一般串定位函数Index(S,T,pos), 设S的串长为n,T的串长为m,则最坏时间复杂度 ;而改进的Index_KMP(S,T,pos) 时间复杂度为 。
第五章:数组和广义表
1.数组的存储结构:以行为主序、以列为主序的地址映像函数 B
2矩阵的压缩存储:
(1)特殊阵:包括对称阵、三角阵、带状阵(利用其特性压缩存储到一维数组)B
(2)稀疏阵 利用的是三元组顺序表来表示 B 用十字链表表示C(本次考试不做要求)
3.广义表定义与存储表示 B (本次考试不做要求)
本章重点:地址映像函数的计算(包括数组和特殊矩阵)
例13.已知n阶下三角矩阵A(即当i
答:n阶下三角矩阵元素A[i][j](1<=i,j<=n,i>=j)。第1列有n个元素,第j列有n-j+1个元素,第1列到第j-1列是等腰梯形,元素数为(n+(n-j+2)(j-1)/2,而aij在第j列上的位置是为i-j+1。所以n阶下三角矩阵A按列存储,其元素aij在一维数组B中的存储位置k与i和j的关系为:
k=(n+(n-(j-1)+1)(j-1)/2+(i-j+1)=(2n-j)(j-1)/2+i
第六章:二叉树与树
1.二叉树的定义和性质: B
几个特殊的二叉树:满二叉树、完全二叉树、二叉排序树、平衡二叉树 B
2.二叉树的顺序存储: C
3.二叉树的链式存储: 用二叉链表表示与实现 A
4.二叉树的遍历:先(中、后)序遍历及应用,相应递归算法和非递归算法 A
5.线索化二叉树(利用二叉链表n+1空指针域来存放某遍历下指向该结点的直接前驱或直接后继,使得蕴含更多信息) B
6.二叉树的应用:算术表达式,霍夫曼树(最优二叉树),判定树 B
7.树的定义和存储表示:…… B
8.树和森林和二叉树的转换 B
9.树与森林的遍历 B
★本章重点:很熟悉二叉树(在二叉链表表示下)的基本操作的递归算法和遍历的非递归算法,请仔细复习。
本章难点:二叉树(含排序树、平衡树)的递归算法和非递归算法。
线索化二叉树及相应操作,重在理解,不考编程!
例14.引入二叉线索树的目的是( )
A.将非线性序列转化成某种线性序列;加快查找结点的前驱或后继的速度
B.为了能在二叉树中方便的进行插入与删除
C.为了能方便的找到双亲 D.使二叉树的遍历结果唯一
A
例15.二叉链表在线索化后,仍不能有效求解的问题是( )。
A.前(先)序线索二叉树中求前(先)序后继 B.中序线索二叉树中求中序后继
C.中序线索二叉树中求中序前驱 D.后序线索二叉树中求后序后继
D
例16.在平衡二叉树中插入一个结点后造成了不平衡,设最低的不平衡结点为A,并已知A的左孩子的平衡因子为-1右孩子的平衡因子为0,则应作( ) 型调整以使其平衡。(平衡因子=左子树深度-右子树深度)
A. LL (单向右旋) B. LR (先左后右双向旋转)
C. RL (先右后左双向旋转) D. RR (单向左旋)
B
例17.一棵非空的二叉树其先序序列和后序序列正好相反,画出这棵二叉树的形状。
先序序列是“根左右” 后序序列是“左右根”,可见对任意结点,若至多只有左子女或至多只有右子女,均可使前序序列与后序序列相反,图示如下:
例18:已知二叉树结点结构如下:
用C语言表示
typedef struct BiNode{
ElemType data;
struct BiNode *lchild,*rchild;
int val;
}BiNode,*BiTree;
其中val域表示该结点的子孙(含孩子结点)的个数。开始时,val域值均为0,T为指向某二叉树根结点的指针。请写算法填写该二叉树中每个结点的val域。
递归算法如下:
int writeVal(BiNode *root)
{if(rootNULL) root->val=0;
else if(root->lchildNULL&&root->rchild==NULL)
root->val=1;
else
root->val=writeVal(root->lchild)+writeVal(root->rchild);
return root->val;
}
例19.编写一个算法,将指针S所指的结点插入到根结点指针为T的二叉排序树中,若已存在则不再插入返回0;否则返回1。(递归的算法见教材)
int Insert_BST( BiTree &T, BiTNode S )
{ BiTree p, q; //p指向当前访问的结点
if(!T) T=S;
else { p=T;
while ( p )
{ q = p; //q指向p结点的双亲结点
if (S->data.key < p->data.key) p = p->lchild;
else if(S->data.key > p->data.key) p = p->rchild;
else p=NULL;
}
if (S->data.key == q->data.key) return 0;
if (S->data.key < q->data.key) q->lchild = S;
else q->rchild = S;
}
return 1;
}
例20.编写一个算法,计算平衡二叉树中所有结点的平衡因子
解:计算一个结点*bt的bf的值递归模型如下:
f(bt): bt->bf 不存在 当btNULL
f(bt): bt->bf=0 当 bt->lchildNULL&&bt->rchild=NULL
f(bt): bt->bf=bt的右子树的高度-左子树的高度 其它情况
可选用先序的方式统计出各个结点的平衡因子
如何求高度呢?递归模型如下:
f(bt): 0 不存在 当btNULL
f(bt): 1 当 bt->lchildNULL&&bt->rchild=NULL
f(bt): bt的左子树和右子树的高度的最大值+1 其它情况
int Height(BSTNode *bt){//求树的高度
int max1,max2;
if(btNULL) return 0;
else if(bt->lchildNULL&&bt->rchild=NULL) return 1;
else{
max1=Height(bt->lchild);
max2=Height(bt->rchild);
return max1>max2?max1+1:max2+1;
}
}
void Countbf(BSTNode *&bt){ //求所有结点的bf
if(bt!=NULL){
if(bt->lchildNULL&&bt->rchild=NULL){
bf->bf=0;
}
else{
Countbf(bt->lchild);
Countbf(bt->rchild);
bt->bf= Height(bt->rchild)-Height(bt->lchild);
}
}
}
实质上可以将上面求bf和求高度合二为一。
int Countbf1(BSTNode *&bt){//求所有结点的bf,返回对应结点高度值
int max1,max2;
if(btNULL) return 0;
if(bt->lchild==NULL&&bt->rchild=NULL){
bf->bf=0;
return1;
}
else{
max1=Height(bt->lchild);
max2=Height(bt->rchild);
bt->bf= max2-max1;
return max1>max2?max1+1:max2+1;
}
}
例21. 设给出一段报文: CAST CAST SAT AT A TASA;字符集合是 { C, A, S, T },各个字符出现的频度(次数)是 W={ 2, 7, 4, 5 };试设计赫夫曼编码,画出赫夫曼树。若给每个字符以等长编码A : 00 T : 10 C : 01 S : 11;试说明赫夫曼编码比此方案的优越之处。(编码最短)
解答见ppt
练习
1.设计一个算法,删除该二叉树,释放所有结点
2.设计一算法判断二叉链表存储的二叉树是否结构对称(左右子树结点结构对称相同)
3.试写出复制一棵二叉树的算法。二叉树采用标准链接结构。
4.习题六 编程 (除打星号的部分)
5. 设计一个算法,寻找二叉树中满足特定数值x的第一个结点(相应的变形:寻找最小值,寻找父结点,寻找兄弟)
6. 设计一个算法,统计二叉树中满足特定数值x结点的个数(相应的变形:统计度为0,1,2的结点)
第七章 图
1.图的定义、基本概念: B
2.图的存储方式:邻接矩阵和邻接表 A
3.图的遍历 深度优先和广度优先 A
4.图的连通性和生成树 B 带权图的最小生成树及算法 B
5.图的最短路径问题 B
6.拓扑排序、AOE网中的关键路径 B
本章重点:熟悉邻接矩阵和邻接表的表示方法,学会编写遍历算法深度优先和广度优先遍历算法以及一些遍历算法的应用。请仔细复习。
本章难点:图的一些算法(如最小生成树、最短路径、关键路径;这部分重在理解算法思想和设计过程)
例22.将邻接矩阵g装换为邻接表G (邻接表的表示方法)
void MatToList(MGragh g,ALGLink &G){
int i,j, N=g.n;//N表示顶点数
ArcNode p;
G=(ALGraph)malloc(sizeof(ALGraph));
for(i=0;i
G->vertices[i].firstedge=NULL;
}
for(i=0;i
for(j=N-1;j>=0;j–)//对第i个顶点进行建立链表(由后向前添加)
if(g.edges[i][j]!=0){
p=(ArcNode *)malloc(sizeof(ArcNode));//新建结点
p->adjvex=j;
p->info=g.edges[i][j];//存放边的权值
p->next=G->vertices[i].firstedge;//前插
G->vertices[i].firstedge=p;
}
G->n=N; G->e=g.e;
}
例23.试利用深度优先遍历DFS判断该图(在邻接表存储下)是否是连通的,若是连通的返回1,若是不连通的返回图的连通分量个数,空图则返回0。(图的遍历)
int visted[MAXNUM]; //全局数组
void DFS (ALGraph* G, int i){/*以Vi为出发点对邻接表图进行DFS */
ArcNode p;
printf(“visit data:%d\n”,G->vertices[i].data);//访问顶点Vi
visited[i]=1; //标记Vi已访问,标志为1
p= G->vertices[i].firstarc; //取Vi边表的头指针
while§ { //依次搜索Vi的邻接点Vj,
if (!visited[p->adjvex]) //若Vj尚未访问,则以Vj为出发点向纵深搜索
DFS (G,p->adjvex);
p=p->next;
}
}
/判断无向图是否连通,若连通返回1/
int Connects(ALGraphG){
int i,flag=1; //flag为标记是否连通
for (i=0;ivexnum;i++)
visited[i]=0 ; //标志向量visted[]初始化,标志为0
DFS(g,0);
for (i=0;ivexnum;i++)
if (visited[i]==0) { //还有vi未访问过,修改标记flag量
flag=0;break;
}
return flag; }
例24.下面是求连通网的最小生成树的prim算法:集合VT,ET分别放顶点和边,初始为( 1 ),下面步骤重复n-1次: a:( 2 );b:( 3 );最后:( 4 )。
(1).A.VT,ET为空 B.VT为所有顶点,ET为空
C.VT为网中任意一点,ET为空 D.VT为空,ET为网中所有边
(2).A. 选i属于VT,j不属于VT,且(i,j)上的权最小
B.选i属于VT,j不属于VT,且(i,j)上的权最大
C.选i不属于VT,j不属于VT,且(i,j)上的权最小
D.选i不属于VT,j不属于VT,且(i,j)上的权最大
(3).A.顶点i加入VT,(i,j)加入ET B. 顶点j加入VT,(i,j)加入ET
C. 顶点j加入VT,(i,j)从ET中删去 D.顶点i,j加入VT,(i,j)加入ET
(4).A.ET 中为最小生成树 B.不在ET中的边构成最小生成树
C.ET中有n-1条边时为生成树,否则无解 D.ET中无回路时,为生成树,否则无解
C A B A
例25.P182 算法 7.12(思考: 用邻接矩阵存储怎么实现?)
练习
1.假设有向图以邻接表存储,计算Vi顶点的出度和入度。
2.在有向无环图中,试利用深度优先遍历DFS求出一个拓扑排序序列。
提示:由某点出发进行深度优先遍历,退出DFS函数调用时记录此时顶点序号,最先退出DFS函数的顶点是拓扑序列中的最后一个顶点,依次下去……得到一个逆向拓扑有序序列;再将此顶点序号反向输出即可。
3. 设计一个深度优先搜索算法,以判断用邻接表方式存储的有向图中是否存在由顶点Vi到顶点Vj(i≠j)的路径。
第八章 查找
基本概念 C
静态查找表中常用的方法:顺序查找、折半查找、分块查找(分别适用于一般、有序、分块有序的表) 相应算法和性能分析 A
动态查找表:二叉排序树的建立、查找、删除;A 二叉平衡树 B
哈希表:哈希函数的构造和冲突处理方法 B
本章重点:查找树的建立和查找(含静态折半查找、动态查找树)、哈希函数和冲突方法
本章难点:二叉排序树删除;平衡排序树的插入
例26.在有序表A[1…12]中,采用二分查找算法查等于A[12]的元素,所比较的元素下标依次为________。
6,9,11,12
例27.设散列表为HT [0…12],即表的大小为m=13。现采用双散列法解决冲突。散列函数和再散列函数分别为:
H0(key)=key % 13; 注:%是求余数运算(=mod)
Hi=(Hi-1+REV(key+1)%11+1) % 13; i=1,2,3,…,m-1
其中,函数REV(x)表示颠倒10进制数x的各位,如REV(37)=73,REV(7)=7等。若插入的关键码序列为(2,8,31,20,19,18,53,27)。
(1)试画出插入这8个关键码后的散列表;(2)计算搜索成功的平均搜索长度ASL。
(1)
散列地址 0 1 2 3 4 5 6 7 8 9 10 11 12
关键字 27 53 2 31 19 20 8 18
比较次数 3 1 1 1 1 1 1 2
(2)ASLsuss =11/8
第九章 内排序
稳定/不稳定排序,内排序和外排序 C
插入排序方法:直接插入排序、折半插入排序、希尔插入排序 算法与性能分析 A
交换排序方法:冒泡排序、快速排序 A
选择排序方法:简单选择排序、堆排序 A
二路归并排序、基数排序 B
排序方法 平均时间 最坏情况 辅助空间 稳定性 不稳定排序举例
直接插入排序 O(n2) O(n2) O(1) 稳定
折半插入排序 O(n2) O(n2) O(1) 稳定
二路插入排序 O(n2) O(n2) O(n) 稳定 本次考试不要求
表插入排序 O(n2) O(n2) O(1) 稳定 本次考试不要求
起泡排序 O(n2) O(n2) O(1) 稳定
直接选择排序 O(n2) O(n2) O(1) 不稳定 2,2’,1
希尔排序 O(n1.3) O(n1.3) O(1) 不稳定 3,2,2’,1(d=2,d=1)
快速排序 O(nlog2n) O(n2) O(log2n) 不稳定 2,2’,1
堆排序 O(nlog2n) O(nlog2n) O(1) 不稳定 2,1,1’(极大堆)
2-路归并排序 O(nlog2n) O(nlog2n) O(n) 稳定
基数排序 O ( d*(rd+n) ) O ( d*(rd+n) ) O (rd ) 稳定
本章重点:各种排序方法的实现、性能比较与选择
例28. 某内排序方法的稳定性是指( )。
A.该排序算法不允许有相同的关键字记录 B.该排序算法允许有相同的关键字记录
C.平均时间为0(n log n)的排序方法 D.以上都不对
B
例29. 对序列{15,9,7,8,20,-1,4}进行排序,进行一趟后数据的排列变为{4,9,-1,8,20,7,15};则采用的是( )排序。
A. 选择 B. 快速 C. 希尔 D. 冒泡
若上题的数据经一趟排序后的排列为{9,15,7,8,20,-1,4},则采用的是( )排序。
A.选择 B. 堆 C. 直接插入 D. 冒泡
C C
例30. 有一组数据(15,9,7,8,20,-1,7,4) 用快速排序的划分方法进行一趟划分后数据的排序为 ( )(按递增序)。
A.下面的B,C,D都不对。 B.9,7,8,4,-1,7,15,20
C.20,15,8,9,7,-1,4,7 D. 9,4,7,8,7,-1,15,20
A
说明: 请针对性的仔细看书和ppt的内容;另外一些经典算法的时间复杂度分析应该不要忽略。
A类 在所有的题型中体现(要求:熟练掌握);
B类 在选择、填空、简答中体现(要求:理解);
C类 在选择、填空中体现(要求:了解)。