各章考核的要点.docx
《各章考核的要点.docx》由会员分享,可在线阅读,更多相关《各章考核的要点.docx(32页珍藏版)》请在冰豆网上搜索。
各章考核的要点
第一部分各章考核的要点
第一章第一章 绪论
本章内容不作考核要求,但同学们对算法的空间复杂度以及时间复杂度度量要了解,同时对抽象数据类型的概念也应有所了解。
第二章线性表
1、1、 二维数组定义、给定下标后计算数组元素实际存放地址
二数组定义为:
二维数组也叫做矩阵,它可以看作是n个行向量和m个列向量所组成的向量。
要注意的是,某一数组元素a[j][k]在数组中的位置由下标的二元组[j][k]唯一确定。
典型例题有:
例1、设有一个二维数组A[1..m,1..n],假设A[1,1]存放位置在644(10),A[3,3]存放位置在676(10),每个元素占一个空间,问A[4,4]在什么位置,下标(10)表示用10进数表示。
【解答】
因为LOC(3,3)=676,LOC(1,1)=644。
则LOC(3,3)=LOC(1,1)+(3-1)*n+(3-1)
676=644+2*n+2
解得n=15
又LOC(4,4)=LOC(1,1)+(4-1)*15+(4-1)=644+3*15+3=692
例2、数组A[1..10,-2..6,2..8]的元素按行顺序存储,第一个元素的首地址为100,每个元素的长度为3,试计算元素A[5,0,7]的存储地址。
【解答】已知第一个元素地址LOC(1,-2,2)=100,每个元素的长度l=3,则
m1=10-1+1=10,m2=6-(-2)+1=9,m3=8-2+1=7,
LOC(5,0,7)=LOC(1,-2,2)+{(5-1)*m2*m3+(0-(-2))*m3+(7-2)}*l=100+{4*9*7+2*7+5}*3=913
2、2、 顺序表的插入与删除算法
(1)
(1)顺序表的插入算法
templateintSeqlist:
:
Insert(Type&x,inti){
//插入x在表中第i个位置处。
函数返回插入是否成功的信息,若为0则插入不成功。
if(i<0||i>last+1||last==MaxSize-1)return0;
else{
last++;
for(intj=last;j>i;j--)data[j]=data[j-1];
data[i]=x;
return1;
}
}
(2)
(2)顺序表的删除算法
templateType*Seqlist:
:
Remove(Type&x){
inti=Find(x);//在表中查找x
if(i>=0){
Typeval=data[i];
last--;
for(intj=i;j<=last;j++)data[j]=data[j+1];
return&val;
}
returnNULL;
}
3、3、 在顺序表中插入及删除元素时计算平均移动元素个数
●● 在已有n个元素的顺序表中插入一个元素,有n+1个插入位置,平均移动元素个数为n/2。
●● 在已有n个元素的顺序表中删除一个元素,有n个删除位置,平均移动元素个数为:
(n-1)/2。
链接表
1、1、单链表(带表头结点和不带表头结点)的插入与删除算法
(1)不带表头结点的插入与删除算法:
●● 插入:
intList:
:
Insert(constintx,constinti){
//将新元素x插入到第i结点之前。
i是结点号,从0开始。
ListNode*p=first;intk=0;
while(p!
=NULL&&klink;k++;}
//循链找第i-1个结点
if(p==NULL&&first!
=NULL){
//非空表而且链短,找不到第i-1个结点
cout<<"InvalidpositionforInsertation!
\n";return0;
//终止插入,函数返回0
}
ListNode*newnode=newListNode(x,NULL);
//建立一个newnode指示的新结点,数据为x
if(first==NULL||i==0){
//插入空表或非空表第一个结点之前
newnode->link=first;
//新结点成为第一个结点
if(first==NULL)last=newnode;
//原为空表时,表尾指针指向这个新结点
first=newnode;
}
else{//插入在链表的中间或尾部
newnode->link=p->link;
if(p->link==NULL)last=newnode;
p->link=newnode;
}
return1;//正常插入,函数返回1
}
●● 删除:
intList:
:
Remove(inti){
//将链表中的第i个元素删去,通过函数返回该元素。
若i不合理,则返回NULL。
if(i<0){cout<<"InvalidpositionforDeletion!
\n";
return0;}//不能删除,函数返回0
ListNode*p=first,*q;intk=0;
while(p!
=NULL&&klink;k++;}
//循链找第i-1个结点
if(p==NULL||p->link==NULL){
//空表或者链短,找不到第i-1个结点
cout<<"InvalidpositionforDeletion!
\n";
return0;//不能删除,函数返回0
}
if(i==0){q=first;p=first=first->link;}
//删第一个结点时,重新拉链
else{q=p->link;p->link=q->link;}
//删中间一个结点或尾结点时
if(q==last)last=p;
//删表尾结点时,表尾指针修改
k=q->data;deleteq;returnk;
//取出被删结点中的数据值
}
2、单链表的递归算法
☞☞搜索含x的结点
templateListNode*Find(ListNode*f,Type&x){
if(f==NULL)returnNULL;
elseif(f->data==x)returnf;
elseFind(f->link,x);
}
☞☞删除x结点(带表头结点)
templateListNode*Delete(ListNode*f,Type&x){
ListNode*p;
if(f->link==NULL)returnNULL;
elseif(f->link->data==x){p=f->link;f->link=p->link;returnp;}
elseDelete(f->link,x);
}
☞☞统计单链表中结点个数
templateintNum(ListNode*f)
{
if(f==NULL)return0;
elsereturn1+Num(f->link);
}
注意以上三个算法均为尾递归算法,要求能利用循环方法,消除尾递归。
例如:
将统计单链表中结点个数的递归算法改为非递归算法如下
templateintNum(ListNode*f){
inti=0;
ListNode*p=f;
while(p!
=NULL){
i++;
p=p->link;
}
returni;
}
☞☞单链表逆置算法:
例:
设有一个表头指针为h的单链表。
试设计一个算法,通过遍历一趟链表,将链表中所有结点的链接方向逆转,如下图所示。
要求逆转结果链表的表头指针h指向原链表的最后一个结点。
【解答1】
templatevoidList:
:
Inverse(){
if(first==NULL)return;
ListNode*p=first→link;,*pr=NULL;
while(p!
=NULL){
first→link=pr;//逆转first指针
pr=first;first=p;p=p→link;//指针前移
}
first->link=pr;
}
【解答2】
templatevoidList:
:
Inverse(){
ListNode*p,*head=newListNode();
while(first!
=NULL){
p=first;first=first→link;//摘下first链头结点
p→link=head→link;head→link=p;//插入head链前端
}
first=head→link;deletehead;//重置first
}
第三章稀疏矩阵与广义表
1、4、 广义表的定义与性质
空表:
长度为0的表。
线性表:
只包括原子的表。
共享表:
可以为其它广义表共享的表。
递归表:
广义表本身可以是自己的子表,具有这种性质的表为共享表。
第四章栈与队列
1、1、 栈、队列与优先级队列的定义
注意:
三者的相同点:
限制存取位置的线性结构。
三者的不同点:
LIFO,FIFO,按优先级出队列
2、2、 用单链表表示栈或队列时栈顶指针或队头、队尾指针初始时指向何处
●● 用单链表表示栈时栈顶指针指向链表的表头;
●● 用单链表表示队列时队头指针指向单链表的第一个结点,队尾指针指向单链表的最后一个结点。
第五章树与二叉树
1、1、 二叉树的几个性质
(1)二叉树各层最大结点数为:
2i(i=0,1,…)
(2)二叉树高度为h时的最大结点数n为:
2h+1-1(h=0,1,…)
(3)完全二叉树有n个结点时的高度h为:
┌log2(n+1)┐-1
(4)完全二叉树顺序存储时结点i的双亲结点、子女结点、兄弟结点的位置(i=0,1,…或i=1,2,…)
1① 若i==0,则结点i为根,无双亲;若i>0,则结点i的双亲结点为:
└(i-1)/2┘。
②若2*i+1③若结点编号i为偶数,且i!
=0,则它的左兄弟为结点i-1;
若结点编号i为奇数,且i!
=n-1,则它的右兄弟为结点i+1
④结点i的层次为:
┌log2(i+1)┐。
2、2、 有n个结点的不同二叉树与二叉搜索树的棵数为:
3、3、 二叉树的前序、中序和后序遍历的递归算法
●● 中序
templatevoidBinaryTree:
:
InOrder(BinTreeNode*current){
if(current!
=NULL){
InOrder(current->leftChild);
Cout<data;
InOrder(current->rightChild);
}
}
●● 前序
templatevoidBinaryTree:
:
PreOrder(BinTreeNode*current){
if(current!
=NULL){
Cout<data;
PreOrder(current->leftChild);
PreOrder(current->rightChild);
}
}
●● 后序
templatevoidBinaryTree:
:
PostOrder(BinTreeNode*current){
if(current!
=NULL){
PostOrder(current->leftChild);
PostOrder(current->rightChild);
Cout<data;
}
}
4、4、 二叉树的递归算法
(1)
(1)求二叉树高度
templateintBinaryTree:
:
Depth(constBinTreeNode){
if(t==NULL)return-1;
elsereturn1+Max(Depth(t->leftChild),Depth(t->right));
}
(2)
(2)求二叉树叶结点个数
template//统计二叉树叶结点个数
intBinaryTree:
:
LeafNum(BinTreeNode*current){
If(current==NULL)return0;
if(current->leftChild==NULL&¤t->rightChild==NULL)
return1;
else
returnLeafNum(current->leftChild)+LeafNum(current->rightChild);
}
(3)交换二叉树根结点的左右子树
template//交换每个结点的左右子女
intBinaryTree:
:
ExchangeChild(BinTreeNode*current){
if(current->leftChild!
=NULL||current->rightChild!
=NULL){
BinTreeNode*temp;
temp=current->leftChild;
current->leftChild=current->rightChild;
current->rightChild=temp;
ExchangeChild(current->leftChild);
ExchangeChild(current->rightChild);
return1;
}
return0;
5、5、 利用二叉树的前序和中序序列及利用中序和后序序列构造二叉树
例1:
已知一棵二叉树的前序遍历的结果序列是ABECDFGHIJ,中序遍历的结果序列是EBCDAFHIGJ,试画出这棵二叉树。
【解答】当前序序列为ABECDFGHIJ,中序序列为EBCDAFHIGJ时:
6、6、 满k叉树的各层最大结点个数、求结点i的双亲结点、孩子结点、兄弟结点的方法。
例:
一棵高度为h的满k叉树有如下性质:
第h层上的结点都是叶结点,其余各层上每个结点都有k棵非空子树,如果按层次自顶向下,同一层自左向右,顺序从1开始对全部结点进行编号,试问:
(1)各层的结点个数是多少?
(2)编号为i的结点的父结点(若存在)的编号是多少?
(3)编号为i的结点的第m个孩子结点(若存在)的编号是多少?
(4)编号为i的结点有右兄弟的条件是什么?
其右兄弟结点的编号是多少?
【解答】
(1)ki(i=0,1,……,h)
(2)
(3)(i-1)*k+m+1
(4)(i-1)modk0或i
时有右兄弟,右兄弟为i+1。
7、k叉正则树中度为0的结点与度为k的结点的关系:
n0=(k-1)nk+1
8、霍夫曼树的构造方法和霍夫曼编码的构造方法,WPL的计算
例:
假定用于通信的电文仅由8个字母c1,c2,c3,c4,c5,c6,c7,c8组成,各字母在电文中出现的频率分别为5,25,3,6,10,11,36,4。
试为这8个字母设计不等长Huffman编码,并给出该电文的总码数。
【解答】
已知字母集{c1,c2,c3,c4,c5,c6,c7,c8}
次数{5,25,3,6,10,11,36,4}
则Huffman编码为
c1
c2
c3
c4
c5
c6
c7
c8
1110
00
1100
1111
100
101
01
1101
电文总码数(WPL)为
妻4*5+2*25+4*3+4*6+3*10+3*11+2*36+4*4
=257
第六章二叉树应用
1、1、 顺序搜索与折半搜索
◆◆构造判定树(扩充二叉搜索树)
◆◆计算搜索成功的平均搜索长度及搜索不成功的平均搜索长度
例:
设有序顺序表中的元素依次为017,094,154,170,275,503,509,512,553,612,677,765,897,908。
试画出对其进行下列查找时的判定树,并计算查找成功的平均查找长度和查找不成功的平均查找长度。
(1)折半查找
(2)顺序查找
【解答】
(1)描述对有序顺序表进行折半查找的判定树为:
ASLsucc=
ASLunsucc=
(2)描述对有序顺序表进行顺序查找的判定树为:
2、2、 二叉搜索树
◆◆搜索含x的结点的算法(分递归和非递归算法)
template
BstNode*BST:
:
Find(constType&x,BstNode*ptr)const{
//递归算法:
在以ptr为根的二叉搜索树中搜索含x的结点。
若找到,则函数返回该结点的地址,否则函数返回NULL值。
if(ptr==NULL)returnNULL;
elseif(xdata)returnFind(x,ptr->leftChild);
//到左子树中继续搜索
elseif(x>ptr->data)returnFind(x,ptr->rightChild);
//到右子树中继续搜索
elsereturnptr;//搜索成功
}
templateBstNode*BST:
:
Find(constType&x,BstNode*ptr)const{
//非递归算法:
说明同上。
if(ptr!
=NULL){//树空返回
BstNode*temp=ptr;//从根开始搜索
while(temp!
=NULL){//==NULL表示搜索失败
if(temp->data==x)returntemp;//搜索成功
if(temp->datarightChild;
//否则,继续搜索右子树
elsetemp=temp->leftChild;
//否则,继续搜索左子树
}
}
returnNULL;
};
◆◆计算搜索成功的平均搜索长度及搜索不成功的平均搜索长度
计算方法同上折半搜索的判定树方法。
3、3、 二叉搜索树的构造方法(不要算法)
见教材P192页。
4、4、 高度为h的二叉搜索树中最大结点个数和最少结点个数
最大结点个数:
2h+1-1
最小结点个数:
h+1
5、5、 AVL树的插入、删除方法及平衡旋转的方法(不要求算法)
例:
设有一个关键字的输入序列{55,31,11,37,46,73,63,02,07},
(1)从空树开始构造AVL树,画出每加入一个新结点时二叉树的形态。
若发生不平衡,指明需做的平衡旋转的类型及平衡旋转的结果。
(2)计算该AVL树在等概率下的查找成功的平均查找长度和查找不成功的平均查找长度。
【解答】
(1)输入序列{55,31,11,37,46,73,63,02,07}时的AVL树构造过程为:
(2)ASLsucc=
(1+2*2+3*4+4*2)=
ASLunsucc=
(3*6+4*4)=
6、6、 高度为h的AVL树中最少结点个数,有n个结点的AVL树的最大高度和最小高度?
例:
对于一个高度为h的AVL树,其最少结点数是多少?
反之,对于一个有n个结点的AVL树,其最大高度是多少?
最小