对含有n个互不相同元素的集合

第七章 查找

1、对含有n个互不相同元素的集合,同时找最大元和最小元至少需进行多少次比较? 找最大元和最小元至少需要进行n-1次比较。

2、若对具有n个元素的有序的顺序表和无序的顺序表分别进行顺序查找,试讨论在查找成功两者在等概率时的平均查找长度: 有序表与无序表一样,都为(n+1)/2。 3、为什么有序的单链表不能进行折半查找?

因为折半查找需要随机知道每个数据元素的位置,这是单链表做不到的。

4、对给定的关键字集合,以不同的次序插入初始为空的树中,是否有可能得到同一棵二叉排序树? 不可能。

5、写出顺序表上实现顺序查找的算法,并将监视哨设在高地址端。 int seqsearch(S_TBL tbl, int key)

{

tbl.elem[0].key = key; int i = 0;

for(i = tbl.length; i >= 0 && tbl.elem[i].key != key; --i) { ;

}

return i; }

6、试写出二分查找的递归算法。

int Binarysearch(S_TBL tbl, int low, int high, int key)

{

if(key == tbl.elem[(low+high)/2]) {

printf(“Find succeed!”); return (low+high)/2;

}

else if(key

return Binarysearch(tbl, low, (low+high)/2-1, key);

} else {

return Binarysearch(tbl, (low+high)/2+1, high-1, key); } }

7、在有序表上顺序查找的算法,监视哨设在高下标端。 int Search_Sq(SSTable ST,int key) {

ST.elem[ST.length+1].key = key; for(i = 1;ST.elem[i].key > key;++i); if(i > ST.length || ST.elem[i].key

return ERROR; }

return i; }/*Search_Sq*/

分析:本算法查找成功情况下的平均查找长度为ST.length/2,不成功情况下为ST.length. 8、折半查找的递归算法。

int Search_Bin_Recursive(SSTable ST,int key,int low,int high) {

if(low > high) {

return 0; /*查找不到时返回*/ }

mid = (low+high)/2;

if(ST.elem[mid].key == key) {

return mid; }

else if(ST.elem[mid].key>key) {

return Search_Bin_Recursive(ST,key,low,mid-1); } else

{

return Search_Bin_Recursive(ST,key,mid+1,high); } }

}//Search_Bin_Recursive

9、折半查找,返回小于或等于待查元素的最后一个结点号。 int Locate_Bin(SSTable ST,int key) {

int *r; r = ST.elem; if(key

return 0;

}

else if(key >= r[ST.length].key) {

return ST.length; } low = 1;

high = ST.length; while(low

mid = (low+high)/2;

if(key >= r[mid].key && key

return mid;

}

else if(key

high = mid; } else {

low = mid;

}

} /*本算法不存在查找失败的情况,不需要return 0*/

}//Locate_Bin

10、分块查找,用折半查找法确定记录所在块,块内采用顺序查找法。 typedef struct {

int maxkey; int firstloc; } Index; typedef struct {

int *elem; int length;

Index idx[MAXBLOCK]; /*每块起始位置和最大元素,其中idx[0]不利用,其内容初始化为{0,0}以利于折半查找*/ int blknum; /*块的数目*/ } IdxSqList; /*索引顺序表类型 */ int Search_IdxSeq(IdxSqList L,int key) {

if(key > L.idx[L.blknum].maxkey) {

return ERROR; /*超过最大元素*/ } low = 1;

high = L.blknum;

found = 0;

while(low

mid = (low+high)/2;

if(key L.idx[mid-1].maxkey) {

found = 1;

}

else if(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

return ERROR; /*未找到*/ }

return k; }/*Search_IdxSeq*/

分析:在块内进行顺序查找时,如果需要设置监视哨,则必须先保存相邻块的相邻元素,以免数据丢失.

11、在有序单循环链表存储结构上的查找算法,假定每次查找都成功。 typedef struct {

LNode *h; /*h指向最小元素*/ LNode *t; /*t指向上次查找的结点*/ } CSList;

LNode *Search_CSList(CSList &L,int key) {

if(L.t->data == key) {

return L.t; }

else if(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指针*/ return p; }/*Search_CSList*/

分析:由于题目中假定每次查找都是成功的,所以本算法中没有关于查找失败的处理.由微积分可得,在等概率情况下,平均查找长度约为n/3.

12、在有序双向循环链表存储结构上的查找算法,假定每次查找都成功。 typedef struct {

DLNode *pre; int data; DLNode *next; } DLNode; typedef struct {

DLNode *sp; int length;

} DSList; /*供查找的双向循环链表类型 */ DLNode *Search_DSList(DSList &L,int key)

{

p = L.sp;

if(p->data > key) {

while(p->data > key) {

p = p->pre; }

L.sp = p; }

else if(p->data

while(p->data

p = p->next; }

L.sp = p; }

return p; }/*Search_DSList*/

13、判断二叉树T是否二叉排序树,是则返回1,否则返回0。 int last = 0; int flag = 1;

int Is_BSTree(Bitree T) {

if(T->lchild && flag) {

Is_BSTree(T->lchild); }

if(T->data

flag=0; /*与其中序前驱相比较*/ }

last = T->data; if(T->rchild && flag) {

Is_BSTree(T->rchild); }

return flag; }/*Is_BSTree */

14、找到二叉排序树T中小于x的最大元素和大于x的最小元素。 int last = 0;

void MaxLT_MinGT(BiTree T,int x) {

if(T->lchild) {

MaxLT_MinGT(T->lchild,x); /*本算法仍是借助中序遍历来实现*/

}

if(lastdata >= x) /*找到了小于x的最大元素*/

{

printf("a=%d\n",last);

}

if(last 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的元素。

void Print_NLT(BiTree T,int x)

{

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元素结点,并释放空间。

void Delete_NLT(BiTree &T,int x)

{

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的元素。 void Print_Between(BiThrTree T,int a,int b)

{

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 */

第七章 查找

1、对含有n个互不相同元素的集合,同时找最大元和最小元至少需进行多少次比较? 找最大元和最小元至少需要进行n-1次比较。

2、若对具有n个元素的有序的顺序表和无序的顺序表分别进行顺序查找,试讨论在查找成功两者在等概率时的平均查找长度: 有序表与无序表一样,都为(n+1)/2。 3、为什么有序的单链表不能进行折半查找?

因为折半查找需要随机知道每个数据元素的位置,这是单链表做不到的。

4、对给定的关键字集合,以不同的次序插入初始为空的树中,是否有可能得到同一棵二叉排序树? 不可能。

5、写出顺序表上实现顺序查找的算法,并将监视哨设在高地址端。 int seqsearch(S_TBL tbl, int key)

{

tbl.elem[0].key = key; int i = 0;

for(i = tbl.length; i >= 0 && tbl.elem[i].key != key; --i) { ;

}

return i; }

6、试写出二分查找的递归算法。

int Binarysearch(S_TBL tbl, int low, int high, int key)

{

if(key == tbl.elem[(low+high)/2]) {

printf(“Find succeed!”); return (low+high)/2;

}

else if(key

return Binarysearch(tbl, low, (low+high)/2-1, key);

} else {

return Binarysearch(tbl, (low+high)/2+1, high-1, key); } }

7、在有序表上顺序查找的算法,监视哨设在高下标端。 int Search_Sq(SSTable ST,int key) {

ST.elem[ST.length+1].key = key; for(i = 1;ST.elem[i].key > key;++i); if(i > ST.length || ST.elem[i].key

return ERROR; }

return i; }/*Search_Sq*/

分析:本算法查找成功情况下的平均查找长度为ST.length/2,不成功情况下为ST.length. 8、折半查找的递归算法。

int Search_Bin_Recursive(SSTable ST,int key,int low,int high) {

if(low > high) {

return 0; /*查找不到时返回*/ }

mid = (low+high)/2;

if(ST.elem[mid].key == key) {

return mid; }

else if(ST.elem[mid].key>key) {

return Search_Bin_Recursive(ST,key,low,mid-1); } else

{

return Search_Bin_Recursive(ST,key,mid+1,high); } }

}//Search_Bin_Recursive

9、折半查找,返回小于或等于待查元素的最后一个结点号。 int Locate_Bin(SSTable ST,int key) {

int *r; r = ST.elem; if(key

return 0;

}

else if(key >= r[ST.length].key) {

return ST.length; } low = 1;

high = ST.length; while(low

mid = (low+high)/2;

if(key >= r[mid].key && key

return mid;

}

else if(key

high = mid; } else {

low = mid;

}

} /*本算法不存在查找失败的情况,不需要return 0*/

}//Locate_Bin

10、分块查找,用折半查找法确定记录所在块,块内采用顺序查找法。 typedef struct {

int maxkey; int firstloc; } Index; typedef struct {

int *elem; int length;

Index idx[MAXBLOCK]; /*每块起始位置和最大元素,其中idx[0]不利用,其内容初始化为{0,0}以利于折半查找*/ int blknum; /*块的数目*/ } IdxSqList; /*索引顺序表类型 */ int Search_IdxSeq(IdxSqList L,int key) {

if(key > L.idx[L.blknum].maxkey) {

return ERROR; /*超过最大元素*/ } low = 1;

high = L.blknum;

found = 0;

while(low

mid = (low+high)/2;

if(key L.idx[mid-1].maxkey) {

found = 1;

}

else if(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

return ERROR; /*未找到*/ }

return k; }/*Search_IdxSeq*/

分析:在块内进行顺序查找时,如果需要设置监视哨,则必须先保存相邻块的相邻元素,以免数据丢失.

11、在有序单循环链表存储结构上的查找算法,假定每次查找都成功。 typedef struct {

LNode *h; /*h指向最小元素*/ LNode *t; /*t指向上次查找的结点*/ } CSList;

LNode *Search_CSList(CSList &L,int key) {

if(L.t->data == key) {

return L.t; }

else if(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指针*/ return p; }/*Search_CSList*/

分析:由于题目中假定每次查找都是成功的,所以本算法中没有关于查找失败的处理.由微积分可得,在等概率情况下,平均查找长度约为n/3.

12、在有序双向循环链表存储结构上的查找算法,假定每次查找都成功。 typedef struct {

DLNode *pre; int data; DLNode *next; } DLNode; typedef struct {

DLNode *sp; int length;

} DSList; /*供查找的双向循环链表类型 */ DLNode *Search_DSList(DSList &L,int key)

{

p = L.sp;

if(p->data > key) {

while(p->data > key) {

p = p->pre; }

L.sp = p; }

else if(p->data

while(p->data

p = p->next; }

L.sp = p; }

return p; }/*Search_DSList*/

13、判断二叉树T是否二叉排序树,是则返回1,否则返回0。 int last = 0; int flag = 1;

int Is_BSTree(Bitree T) {

if(T->lchild && flag) {

Is_BSTree(T->lchild); }

if(T->data

flag=0; /*与其中序前驱相比较*/ }

last = T->data; if(T->rchild && flag) {

Is_BSTree(T->rchild); }

return flag; }/*Is_BSTree */

14、找到二叉排序树T中小于x的最大元素和大于x的最小元素。 int last = 0;

void MaxLT_MinGT(BiTree T,int x) {

if(T->lchild) {

MaxLT_MinGT(T->lchild,x); /*本算法仍是借助中序遍历来实现*/

}

if(lastdata >= x) /*找到了小于x的最大元素*/

{

printf("a=%d\n",last);

}

if(last 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的元素。

void Print_NLT(BiTree T,int x)

{

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元素结点,并释放空间。

void Delete_NLT(BiTree &T,int x)

{

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的元素。 void Print_Between(BiThrTree T,int a,int b)

{

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 */


相关内容

  • 高数必修一1-1集合与集合的表示方法练习题
  • 1.1 集合 1.1.1 集合的含义与表示 第1课时 集合的含义 一.基础过关 1. 下列各项中,不可以组成集合的是 ( ) A.所有的正数 B.等于2的数 C.接近于0的数 D.不等于0的偶数 2. 集合A中只含有元素a,则下列各式正确的是 ( ) A.0∈A B.a∉A C.a∈A D.a=A ...

  • 高中数学(必修一)重点难点解析
  • 高中数学(必修一)重点难点解析 第一章 集合 §1.1 集合的概念与运算 一.知识导学 1. 集合:一般地,一定范围内某些确定的.不同的对象的全体构成一个集合. 2. 元素:集合中的每一个对象称为该集合的元素,简称元. 3. 子集:如果集合A 的任意一个元素都是集合B 的元素(若a ∉A 则a ∈B ...

  • 集合的含义与表示知识点
  • 集合的含义与表示 一 集合与元素 1.集合:一般地,一定范围内某些确定的.不同的对象的全体构成一个集合(set).集合常用大写的拉丁字母来表示,如集合A.集合B„„:集合中的每一个对象称为该集合的元素(element),简称元.集合的元素常用小写的拉丁字母来表示.如a.b.c.p.q„„ 指出下列对 ...

  • 集合的概念教材解读
  • 集合的概念教材解读 湖南祁东育贤中学 周友良 421600 湖南省祁东县洪桥镇一中 徐秋蓉 一.内容分析: 1以说,从开始学习数学就离不开对逻辑知识的掌握和运用,基本的逻辑知识在日常生活.学习.工作中,也2 把集合的初步知识与简易逻辑知识安排在高中数学的最开始,是因为在高中数学中,这些知识与其他内容 ...

  • 集合的基础知识
  • 写在前面的话 1.朋友们的热心,是qzzn(求职指南论坛)行政职业能力测试版发展的动力!也是加入到qzzn的各位朋友共有的财富! 2.所有汇编资料,免费提供,仅供大家交流和学习.请在学习结束后,自行删除! 3.严禁用于商业用途! 4.希望在公务员考试的道路上,有qzzn,有行政职业能力测试版的陪伴, ...

  • 集合及其表示法
  • §1.1 集合及其表示法 教学目的: 1.理解集合.空集的意义: 2.会正确使用集合的表示法:列举法.描述法和图示法: 3.掌握常见数集的英文字母表示. 重点:1.集合的本质属性:2.如何正确表示一个集合:3.常见数集的英文字母表示. 难点:1.0.{0}..{}的区别:2.描述法中符号书写的规 ...

  • 集合知识点+基础习题(有答案)
  • 集合练习题 知识点 一般地,我们把研究对象统称为元素,把一些元素组成的总体叫做集合(简称集). 1.集合中元素具的有几个特征 ⑴确定性-因集合是由一些元素组成的总体,当然,我们所说的"一些元素"是确定的. ⑵互异性-即集合中的元素是互不相同的,如果出现了两个(或几个)相同的元素就 ...

  • 1.2集合之间的关系与运算
  • §1.2 集合之间的关系与运算 1.2.1 集合之间的关系 知识梳理 1.(1)任意一个 A⊆B B⊇A A包含于B B包含A (2)子集 ⊆ (3)子集 不属于 AB BA (4)⊆ 2.= A⊆B B⊆A 3.A⊆B ⇔ 作业设计 1.B [∵P={x|yx+1}={x|x≥-1},Q={y|y ...

  • 集合的含义及其表示教案
  • 集合的含义及其表示教案 教材分析:集合概念的基本理论,称为集合论.它是近.现代数学的一个重要基础.一方面,许多重要的数学分支,如数理逻辑.近世代数.实变函数.泛函分析.概率统计.拓扑等,都建立在集合理论的基础上.另一方面,集合论及其反映的数学思想,在越来越广泛的领域中得到应用.在小学和初中数学中,学 ...