数据结构课后习题答案第九章
else if (s[mi].key>k
return(binsearch(s,low,mid-1,k)
else return(mid);
}
else return(0);
} // 算法结束
9.5 int level(bstnode *bst, keytype K)
// 在二叉排序树bst中,求关键字K所在结点的层次
q->next=p->next;
while (q!=L && q->freq<p-freq) q=q->prior; // 找p结点位置
q->next->prior=p; // 将p结点插入链表
p->next=q->next;
p->prior=q;
q->next=p;
} // 算法结束
void locate(snode L[],int n;keytype X)
else { freq=L[i].freq;
while ( L[i-1].freq<freq) { L[i].freq=L[l-1].freq; i--; }
L[i+1].freq=freq;
}
} // 算法结束
9.3
注:判定树中的编号为元素在有序表中的序号
9.4 int binsearch(rectype s[],int low,int high, keytype k)
if(p= =null){printf(“没有关键字k”);return(null);}
else{pre->next=p->next;free(p);return(k);}
}
}//hashdelete
9.12(1)
0 1 2 3 4 5 6 7 8 9 10 11 12
14
01
68
27
55
19
20
84
{bstnode *p; // p为工作指针
int num=0; // 记层数
p=bst;
while (p && p->key!=K) // 二叉排序树不空 且关键字不等
if (p->key<K) { num++; p=p->rchild; } // 沿右子树
else { num++; p=p->lchild; } // 沿左子树
if (i>0 && r[i].key==k) return(i);
else 过程的判定树是单支树。
查找成功的平均查找长度为
ASL=∑PICI =1/n*∑i = 1/2*(n+1)
查找不成功的平均查找长度为 ASL=1/(n+1)(∑i+(n+1))=(n+2)/2.
// 为1,调用本函数后,若仍为1,是二叉排序树,否则,不是二叉排序树。
{if (bst!=null)
{bstree(bst->lchild,pre);
if (pre==null) pre=bst;
else if (pre->key>bst->key)
{printf (“非二叉排序树\n”);flag=0; return 0;}
// 有序的顺序表s,其元素的低端和高端下标分别为low和 high.
// 本算法递归地折半查找关键字为k的数据元素,若存在,则返回其在有序
// 顺序表中的位置,否则,返回0。
{ if (low<=high)
{mid=(low+high)/2;
if (s[mid].key<k )
return binsearch(s,mid+1,high,k);
(2)
0
1
2
3
4
5
6
7
8
9
10
11
12
查找成功时平均查找长度=(1*6+4*2+1*3+1*4)/12=21/12
查找不成功时的平均查找长度=(1*7+2*2+3*3+1*5)/13=25/13
9.13各种查找方法均有优点和缺点,不能笼统地说某种方法的好坏。
顺序查找的时间为o(n),在n较小时使用较好,它对数据元素的排列没有要求;二分查找时间为o(log2n),效率高但它要求数据元素有序排列;散查找时间为o(1),它只能按关键字随机查找(使用散列函数),不能顺序查找,也不能折半查找。
else pre=p;
bstree(bst->rchild,pre);
}
}
9.8(1)
ASL=(1*1+2*2+3*3+3*4+2*5+1*6)/12=42/12
(2)
L
R
(一)
R
L
(二)
R
R
(三)
(四)
ASL=(1*1+2*2+4*3+4*4+1*5)/12=38/12
9.9
L
LR
L
RL
(LL型)(LR型)(RL型)
R
R
(RR型)
9.10
(1)插入关键字B后,B-树的结点无变化
(2)插入关键字L后,结点E和G产生分裂
(3)插入关键字P后,结点H产生分裂
(4)插入关键字Q后,结点不变
(5)插入关键字R后,三个层次结点产生分裂,使B-树增高
9.11hegtype hashdelete(hashtable ht,hegtype k)
H(11)=11%13=11
H(10)=10%13=10冲突,3次成功
H(79)=79%13=1冲突,9次成功
成功时的平均查找长度=(1*6+1*2+3*3+1*4+1*9)/12=30/12
查找不成功时的平均查找长度=(1+13+12+11+10+9+8+7+6+5+4+3+2+1)/13=92/13
else return(ancestor(p->rchild)); // 沿右子树
} // 算法结束
9.7 int bstree(bstnode *bst, bstnode *pre)
// bst是二叉树根结点的指针,pre总指向当前访问结点的前驱,调用本函数
// 时为null。本算法判断bst是否是二叉排序树。设一全程变量flag,初始值
else if (p->key==b) { printf(“B 是A的祖先。\n”); return(p); }
else if (p-key>a && p->key<b) return(p);/ p是A和B的最近公共祖先
else if (p->key>b) return(ancestor(p->lchild)); // 沿左子树
if (p->key==K) return (++num); // 查找成功
else return(0); // 查找失败
} // 算法结束
其递归算法如下:
int level(bstnode *bst, keytype K,int num)
// 在二叉排序树中,求关键字K所在结点的层次的递归算法,调用时num=0
{if (bst==null) return 0;
else if (bst->key==K) return ++num;
else if (bst->key<K) return(bst->rchild,K,num++);
else return(bst->lchild,K,num++);
} // 算法结束
//ht是拉链法解决冲突的散列表,本算法删除关键字
//为k的指定结点,若删除成功,返回K;否则
//返回null
{设I=H(heg);//I为关键字k用指定哈希函数计算的哈希地址
if(ht[i]=null) {printf(“没有关键字k”);return(null);}
else{p=ht[i];pre=p;while(p&&p->data!=k){pre=p;p=p->next;}
79
23
11
10
121431139113
H(19)=19%13=6
H(14)=14%13=1
H(23)=23%13=10
H(01)=01%13=1冲突,2次成功
H(68)=68%13=3
H(20)=20%13=7
H(84)=84%13=6冲突,3次成功
H(27)=27%13=1冲突,4次成功
H(55)=55%13=3冲突,3次成功
9.6 bstnode *ancestor(bstnode *bst)
// bst是非空二叉排序树根结点的指针。
// A和B是bst树上的两个不同结点,本算法求A和B的最近公共祖先。
// 设A和B的关键字分别为a和b,不失一般性,设a<b。
{bstnode *p=bst;
if (p->key==a) { printf(“A 是B的祖先。\n”); return(p); }
keytype key; // 关键字
ElemType other;
}snode;
void locate(seqlist L,keytype X)
// 在链表中查找给定值为X的结点,并保持访问频繁的结点在前