对含有n个互不相同元素的集合.docx
《对含有n个互不相同元素的集合.docx》由会员分享,可在线阅读,更多相关《对含有n个互不相同元素的集合.docx(11页珍藏版)》请在冰豆网上搜索。
![对含有n个互不相同元素的集合.docx](https://file1.bdocx.com/fileroot1/2023-1/10/273eb2b2-d394-4b01-8af7-02fa83daf45a/273eb2b2-d394-4b01-8af7-02fa83daf45a1.gif)
对含有n个互不相同元素的集合
第七章查找
1、对含有n个互不相同元素的集合,同时找最大元和最小元至少需进行多少次比较?
找最大元和最小元至少需要进行n-1次比较。
2、若对具有n个元素的有序的顺序表和无序的顺序表分别进行顺序查找,试讨论在查找成功两者在等概率时的平均查找长度:
有序表与无序表一样,都为(n+1)/2。
3、为什么有序的单链表不能进行折半查找?
因为折半查找需要随机知道每个数据元素的位置,这是单链表做不到的。
4、对给定的关键字集合,以不同的次序插入初始为空的树中,是否有可能得到同一棵二叉排序树?
不可能。
5、写出顺序表上实现顺序查找的算法,并将监视哨设在高地址端。
intseqsearch(S_TBLtbl,intkey)
{
tbl.elem[0].key=key;
inti=0;
for(i=tbl.length;i>=0&&tbl.elem[i].key!
=key;--i)
{
;
}
returni;
}
6、试写出二分查找的递归算法。
intBinarysearch(S_TBLtbl,intlow,inthigh,intkey)
{
if(key==tbl.elem[(low+high)/2])
{
printf(“Findsucceed!
”);
return(low+high)/2;
}
elseif(key{
returnBinarysearch(tbl,low,(low+high)/2-1,key);
}
else
{
returnBinarysearch(tbl,(low+high)/2+1,high-1,key);
}
}
7、在有序表上顺序查找的算法,监视哨设在高下标端。
intSearch_Sq(SSTableST,intkey)
{
ST.elem[ST.length+1].key=key;
for(i=1;ST.elem[i].key>key;++i);
if(i>ST.length||ST.elem[i].key{
returnERROR;
}
returni;
}/*Search_Sq*/
分析:
本算法查找成功情况下的平均查找长度为ST.length/2,不成功情况下为ST.length.
8、折半查找的递归算法。
intSearch_Bin_Recursive(SSTableST,intkey,intlow,inthigh)
{
if(low>high)
{
return0;/*查找不到时返回*/
}
mid=(low+high)/2;
if(ST.elem[mid].key==key)
{
returnmid;
}
elseif(ST.elem[mid].key>key)
{
returnSearch_Bin_Recursive(ST,key,low,mid-1);
}
else
{
returnSearch_Bin_Recursive(ST,key,mid+1,high);
}
}
}//Search_Bin_Recursive
9、折半查找,返回小于或等于待查元素的最后一个结点号。
intLocate_Bin(SSTableST,intkey)
{
int*r;
r=ST.elem;
if(key{
return0;
}
elseif(key>=r[ST.length].key)
{
returnST.length;
}
low=1;
high=ST.length;
while(low<=high)
{
mid=(low+high)/2;
if(key>=r[mid].key&&key{
returnmid;
}
elseif(key{
high=mid;
}
else
{
low=mid;
}
}/*本算法不存在查找失败的情况,不需要return0*/
}//Locate_Bin
10、分块查找,用折半查找法确定记录所在块,块内采用顺序查找法。
typedefstruct
{
intmaxkey;
intfirstloc;
}Index;
typedefstruct
{
int*elem;
intlength;
Indexidx[MAXBLOCK];/*每块起始位置和最大元素,其中idx[0]不利用,其内容初始化为{0,0}以利于折半查找*/
intblknum;/*块的数目*/
}IdxSqList;/*索引顺序表类型*/
intSearch_IdxSeq(IdxSqListL,intkey)
{
if(key>L.idx[L.blknum].maxkey)
{
returnERROR;/*超过最大元素*/
}
low=1;
high=L.blknum;
found=0;
while(low<=high&&!
found)/*折半查找记录所在块号mid*/
{
mid=(low+high)/2;
if(key<=L.idx[mid].maxkey&&key>L.idx[mid-1].maxkey)
{
found=1;
}
elseif(key>L.idx[mid].maxkey)
{
low=mid+1;
}
else
{
high=mid-1;
}
}
i=L.idx[mid].firstloc;/*块的下界*/
j=i+blksize-1;/*块的上界*/
temp=L.elem[i-1];/保存相邻元素*/
L.elem[i-1]=key;/*设置监视哨*/
for(k=j;L.elem[k]!
=key;--k);/*顺序查找*/
L.elem[i-1]=temp;/*恢复元素*/
if(k
{
returnERROR;/*未找到*/
}
returnk;
}/*Search_IdxSeq*/
分析:
在块内进行顺序查找时,如果需要设置监视哨,则必须先保存相邻块的相邻元素,以免数据丢失.
11、在有序单循环链表存储结构上的查找算法,假定每次查找都成功。
typedefstruct
{
LNode*h;/*h指向最小元素*/
LNode*t;/*t指向上次查找的结点*/
}CSList;
LNode*Search_CSList(CSList&L,intkey)
{
if(L.t->data==key)
{
returnL.t;
}
elseif(L.t->data>key)
{
for(p=L.h,i=1;p->data!
=key;p=p->next,++i);
}
else
{
for(p=L.t,i=L.tpos;p->data!
=key;p=p->next,++i);
}
L.t=p;/*更新t指针*/
returnp;
}/*Search_CSList*/
分析:
由于题目中假定每次查找都是成功的,所以本算法中没有关于查找失败的处理.由微积分可得,在等概率情况下,平均查找长度约为n/3.
12、在有序双向循环链表存储结构上的查找算法,假定每次查找都成功。
typedefstruct
{
DLNode*pre;
intdata;
DLNode*next;
}DLNode;
typedefstruct
{
DLNode*sp;
intlength;
}DSList;/*供查找的双向循环链表类型*/
DLNode*Search_DSList(DSList&L,intkey)
{
p=L.sp;
if(p->data>key)
{
while(p->data>key)
{
p=p->pre;
}
L.sp=p;
}
elseif(p->data {
while(p->data{
p=p->next;
}
L.sp=p;
}
returnp;
}/*Search_DSList*/
13、判断二叉树T是否二叉排序树,是则返回1,否则返回0。
intlast=0;
intflag=1;
intIs_BSTree(BitreeT)
{
if(T->lchild&&flag)
{
Is_BSTree(T->lchild);
}
if(T->data{
flag=0;/*与其中序前驱相比较*/
}
last=T->data;
if(T->rchild&&flag)
{
Is_BSTree(T->rchild);
}
returnflag;
}/*Is_BSTree*/
14、找到二叉排序树T中小于x的最大元素和大于x的最小元素。
intlast=0;
voidMaxLT_MinGT(BiTreeT,intx)
{
if(T->lchild)
{
MaxLT_MinGT(T->lchild,x);/*本算法仍是借助中序遍历来实现*/
}
if(lastdata>=x)/*找到了小于x的最大元素*/
{
printf("a=%d\n",last);
}
if(last<=x&&T->data>x)/*找到了大于x的最小元素*/
{
printf("b=%d\n",T->data);
}
last=T->data;
if(T->rchild)
{
MaxLT_MinGT(T->rchild,x);
}
}/*MaxLT_MinGT*/
15、从大到小输出二叉排序树T中所有不小于x的元素。
voidPrint_NLT(BiTreeT,intx)
{
if(T->rchild)
{
Print_NLT(T->rchild,x);
}
if(T->data{
exit();/*当遇到小于x的元素时立即结束运行*/
}
printf("%d\n",T->data);
if(T->lchild)
{
Print_NLT(T->lchild,x);/*先右后左的中序遍历*/
}
}/*Print_NLT*/
16、删除二叉排序树T中所有不小于x元素结点,并释放空间。
voidDelete_NLT(BiTree&T,intx)
{
if(T->rchild)
{
Delete_NLT(T->rchild,x);
}
if(T->data{
exit();/*当遇到小于x的元素时立即结束运行*/
}
q=T;
T=T->lchild;
free(q);/*如果树根不小于x,则删除树根,并以左子树的根作为新的树根*/
if(T)
{
Delete_NLT(T,x);/*继续在左子树中执行算法*/
}
}/*Delete_NLT*/
17、打印输出后继线索二叉排序树T中所有大于a且小于b的元素。
voidPrint_Between(BiThrTreeT,inta,intb)
{
p=T;
while(!
p->ltag)
{
p=p->lchild;/*找到最小元素*/
}
while(p&&p->data
{
if(p->data>a)
{
printf("%d\n",p->data);/*输出符合条件的元素*/
}
if(p->rtag)
{
p=p->rtag;
}
else
{
p=p->rchild;
while(!
p->ltag)
{
p=p->lchild;
}
}/*转到中序后继*/
}/*while*/
}/*Print_Between*/