高中数学必修一 集合与搜索.docx

上传人:b****1 文档编号:13352290 上传时间:2023-06-13 格式:DOCX 页数:39 大小:93.69KB
下载 相关 举报
高中数学必修一 集合与搜索.docx_第1页
第1页 / 共39页
高中数学必修一 集合与搜索.docx_第2页
第2页 / 共39页
高中数学必修一 集合与搜索.docx_第3页
第3页 / 共39页
高中数学必修一 集合与搜索.docx_第4页
第4页 / 共39页
高中数学必修一 集合与搜索.docx_第5页
第5页 / 共39页
高中数学必修一 集合与搜索.docx_第6页
第6页 / 共39页
高中数学必修一 集合与搜索.docx_第7页
第7页 / 共39页
高中数学必修一 集合与搜索.docx_第8页
第8页 / 共39页
高中数学必修一 集合与搜索.docx_第9页
第9页 / 共39页
高中数学必修一 集合与搜索.docx_第10页
第10页 / 共39页
高中数学必修一 集合与搜索.docx_第11页
第11页 / 共39页
高中数学必修一 集合与搜索.docx_第12页
第12页 / 共39页
高中数学必修一 集合与搜索.docx_第13页
第13页 / 共39页
高中数学必修一 集合与搜索.docx_第14页
第14页 / 共39页
高中数学必修一 集合与搜索.docx_第15页
第15页 / 共39页
高中数学必修一 集合与搜索.docx_第16页
第16页 / 共39页
高中数学必修一 集合与搜索.docx_第17页
第17页 / 共39页
高中数学必修一 集合与搜索.docx_第18页
第18页 / 共39页
高中数学必修一 集合与搜索.docx_第19页
第19页 / 共39页
高中数学必修一 集合与搜索.docx_第20页
第20页 / 共39页
亲,该文档总共39页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

高中数学必修一 集合与搜索.docx

《高中数学必修一 集合与搜索.docx》由会员分享,可在线阅读,更多相关《高中数学必修一 集合与搜索.docx(39页珍藏版)》请在冰点文库上搜索。

高中数学必修一 集合与搜索.docx

高中数学必修一集合与搜索

第7章集合与搜索

7-1设A={1,2,3},B={3,4,5},求下列结果:

(1)A+B

(2)A*B(3)A-B

(4)A.Contains

(1)(5)A.AddMember

(1)(6)A.DelMember

(1)(7)A.Min()

【解答】

(1)集合的并A+B={1,2,3,4,5}

(2)集合的交A*B={3}

(3)集合的差A-B={1,2}

(4)包含A.Contains

(1)=1,表示运算结果为"True"

(5)增加A.AddMember

(1),集合中仍为{1,2,3},因为增加的是重复元素,所以不加入

(6)删除A.DelMember

(1),集合中为{2,3}

(7)求最小元素A.Min(),结果为1

7-2试编写一个算法,打印一个有穷集合中的所有成员。

要求使用集合抽象数据类型中的基本操作。

如果集合中包含有子集合,各个子集合之间没有重复的元素,采用什么结构比较合适。

【解答】

集合抽象数据类型的部分内容

templateclassSet{

//对象:

零个或多个成员的聚集。

其中所有成员的类型是一致的,但没有一个成员是相同的。

intContains(constTypex);//判元素x是否集合this的成员

intSubSet(Set&right);//判集合this是否集合right的子集

intoperator==(Set&right);//判集合this与集合right是否相等

intElemtype();//返回集合元素的类型

TypeGetData();//返回集合原子元素的值

charGetName();//返回集合this的集合名

Set*GetSubSet();//返回集合this的子集合地址

Set*GetNext();//返回集合this的直接后继集合元素

intIsEmpty();//判断集合this是否空。

空则返回1,否则返回0

};

ostream&operator<<(ostream&out,Sett){

//友元函数,将集合t输出到输出流对象out。

t.traverse(out,t);returnout;

}

voidtraverse(ostream&out,Sets){

//友元函数,集合的遍历算法

if(s.IsEmpty()==0){//集合元素不空

if(s.Elemtype()==0)out<

elseif(s.Elemtype()==1){//集合原子元素

out<

if(s.GetNext()!

=NULL)out<<‘,’;

}

else{//子集合

traverse(s.GetSubSet());//输出子集合

if(s.GetNext()!

=NULL)out<<‘,’;

}

traverse(s.GetNext());//向同一集合下一元素搜索

}

elseout<<‘}’;

}

如果集合中包含有子集合,各个子集合之间没有重复的元素,采用广义表结构比较合适。

也可以使用并查集结构。

7-3当全集合可以映射成1到N之间的整数时,可以用位数组来表示它的任一子集合。

当全集合是下列集合时,应当建立什么样的映射?

用映射对照表表示。

(1)整数0,1,…,99

(2)从n到m的所有整数,nm

(3)整数n,n+2,n+4,…,n+2k

(4)字母‘a’,‘b’,‘c’,…,‘z’

(5)两个字母组成的字符串,其中,每个字母取自‘a’,‘b’,‘c’,…,‘z’。

【解答】

(1)i→i的映射关系,i=0,1,2,…,99

(2)i→n-i的映射关系,i=n,n+1,n+2,…,m

0

1

2

m-n

n

n+1

n+2

m

(3)i→(i-n)/2的映射关系,i=n,n+2,n+4,…,n+2k

0

1

2

k

n

n+2

n+4

n+2k

(4)ord(c)→ord(c)-ord('a')的映射关系,c='a','b','c',…,'z'

0

1

2

25

'a'

'b'

'c'

'z'

(5)(ord(c1)-ord('a'))*26+ord(c2)-ord('a')的映射关系,c1=c2='a','b','c',…,'z'

0

1

2

675

'aa'

'ab'

'ba'

'zz'

7-4试证明:

集合A是集合B的子集的充分必要条件是集合A和集合B的交集是A。

【证明】

必要条件:

因为集合A是集合B的子集,有AB,此时,对于任一xA,必有xB,因此可以推得xA∩B,就是说,如果A是B的子集,一定有A∩B=A。

充分条件:

如果集合A和集合B的交集A∩B是A,则对于任一xA,一定有xA∩B,因此可以推得xB,由此可得AB,即集合A是集合B的子集。

7-5试证明:

集合A是集合B的子集的充分必要条件是集合A和集合B的并集是B。

【证明】

必要条件:

因为集合A是集合B的子集,有AB,此时,对于任一xA,必有xB,它一定在A∪B中。

另一方面,对于那些x'A,但x'B的元素,它也必在A∪B中,因此可以得出结论:

凡是属于集合B的元素一定在A∪B中,A∪B=B。

充分条件:

如果存在元素xA且xB,有xA∪B,但这不符合集合A和集合B的并集A∪B是B的要求。

集合的并A∪B是集合B的要求表明,对于任一xA∪B,同时应有xB。

对于那些满足x'A的x',既然x'A∪B,也应当x'B,因此,在此种情况下集合A应是集合B的子集。

7-6设+、*、-是集合的或、与、差运算,试举一个例子,验证

A+B=(A-B)+(B-A)+A*B

【解答】

若设集合A={1,3,4,7,9,15},集合B={2,3,5,6,7,12,15,17}。

A+B={1,2,3,4,5,6,7,9,12,15,17}

又A*B={3,7,15},A–B={1,4,9},B–A={2,5,6,12,17}

则(A–B)+(B–A)+A*B={1,2,3,4,5,6,7,9,12,15,17}

有A+B=(A–B)+(B–A)+A*B。

7-7给定一个用无序链表表示的集合,需要在其上执行operator+(),operator*(),operator-(),Contains(x),AddMember(x),DelMember(x),Min(),试写出它的类声明,并给出所有这些成员函数的实现。

【解答】

下面给出用无序链表表示集合时的类的声明。

templateclassSet;//用以表示集合的无序链表的类的前视定义

templateclassSetNode{//集合的结点类定义

friendclassSetList;

private:

Typedata;//每个成员的数据

SetNode*link;//链接指针

public:

SetNode(constType&item):

data(item),link(NULL);//构造函数

};

templateclassSet{//集合的类定义

private:

SetNode*first,*last;//无序链表的表头指针,表尾指针

public:

SetList(){first=last=newSetNode(0);}//构造函数

~SetList(){MakeEmpty();deletefirst;}//析构函数

voidMakeEmpty();//置空集合

intAddMember(constType&x);//把新元素x加入到集合之中

intDelMember(constType&x);//把集合中成员x删去

Set&operator=(Set&right);//复制集合right到this。

Set&operator+(Set&right);//求集合this与集合right的并

Set&operator*(Set&right);//求集合this与集合right的交

Set&operator-(Set&right);//求集合this与集合right的差

intContains(constType&x);//判x是否集合的成员

intoperator==(Set&right);//判集合this与集合right相等

Type&Min();//返回集合中的最小元素的值

}

(1)operator+()

templateSet&Set:

:

operator+(Set&right){

//求集合this与集合right的并,计算结果通过临时集合temp返回,this集合与right集合不变。

SetNode*pb=right.first->link;//right集合的链扫描指针

SetNode*pa,*pc;//this集合的链扫描指针和结果链的存放指针

Settemp;

pa=first->link;pc=temp.first;

while(pa!

=NULL){//首先把集合this的所有元素复制到结果链

pc->link=newSetNode(pa->data);

pa=pa->link;pc=pc->link;

}

while(pb!

=NULL){//将集合right中元素一个个拿出到this中查重

pa=first->link;

while(pa!

=NULL&&pa->data!

=pb->data)pa=pa->link;

if(pa==NULL)//在集合this中未出现,链入到结果链

{pc->link=newSetNode(pa->data);pc=pc->link;}

pb=pb->link;

}

pc->link=NULL;last=pc;//链表收尾

returntemp;

}

(2)operator*()

templateSet&Set:

:

operator*(Set&right){

//求集合this与集合right的交,计算结果通过临时集合temp返回,this集合与right集合不变。

SetNode*pb=right.first->link;//right集合的链扫描指针

Settemp;

SetNode*pc=temp.first;//结果链的存放指针

while(pb!

=NULL){//将集合right中元素一个个拿出到this中查重

SetNode*pa=first->link;//this集合的链扫描指针

while(pa!

=NULL){

if(pa->data==pb->data)//两集合公有的元素,插入到结果链

{pc->link=newSetNode(pa->data);pc=pc->link;}

pa=pa->link;

}

pb=pb->link;

}

pc->link=NULL;last=pc;//置链尾指针

returntemp;

}

(3)operator-(),

templateSet&Set:

:

operator-(Set&right){

//求集合this与集合right的差,计算结果通过临时集合temp返回,this集合与right集合不变。

SetNode*pa=first->link;//this集合的链扫描指针

Settemp;

SetNode*pc=temp->first;//结果链的存放指针

while(pa!

=NULL){//将集合this中元素一个个拿出到right中查重

SetNode*pb=right.first->link;//right集合的链扫描指针

while(pb!

=NULL&&pa->data!

=pb->data)

pb=pb->link;

if(pb==NULL)//此this中的元素在right中未找到,插入

{pc->link=newSetNode(pa->data);pc=pc->link;}

pa=pa->link;

}

pc->link=NULL;last=pc;//链表收尾

returntemp;

}

(4)Contains(x)

templateintSet:

:

Contains(constType&x){

//测试函数:

如果x是集合的成员,则函数返回1,否则返回0。

SetNode*temp=first->link;//链的扫描指针

while(temp!

=NULL&&temp->data!

=x)temp=temp->link;//循链搜索

if(temp!

=NULL)return1;//找到,返回1

elsereturn0;//未找到,返回0

}

(5)AddMember(x)

templateintSet:

:

AddMember(constType&x){

//把新元素x加入到集合之中。

若集合中已有此元素,则函数返回0,否则函数返回1。

SetNode*temp=first->link;//temp是扫描指针

while(temp!

=NULL&&temp->data!

=x)temp=temp->link;/循链扫描

if(temp!

=NULL)return0;//集合中已有此元素,不加

last=last->link=newSetNode(x);//否则,创建数据值为x的新结点,链入

return1;

}

(6)DelMember(x)

templateintSet:

:

DelMember(constType&x){

//把集合中成员x删去。

若集合不空且元素x在集合中,则函数返回1,否则返回0。

SetNode*p=first->link,*q=first;

while(p!

=NULL){

if(p->data==x){//找到

q->link=p->link;//重新链接

if(p==last)last=q;//删去链尾结点时改链尾指针

deletep;return1;//删除含x结点

}

else{q=p;p=p->link;}//循链扫描

return0;//集合中无此元素

}

(7)Min()

templateSetNode*Set:

:

Min(){

//在集合中寻找值最小的成员并返回它的位置。

SetNode*p=first->link,*q=first->link;//p是检测指针,q是记忆最小指针

while(p!

=NULL){

if(p->datadata)q=p;//找到更小的,让q记忆它

p=p->link;//继续检测

}

returnq;

}

7-8设有序顺序表中的元素依次为017,094,154,170,275,503,509,512,553,612,677,765,897,908。

试画出对其进行折半搜索时的二叉搜索树,并计算搜索成功的平均搜索长度和搜索不成功的平均搜索长度。

【解答】

509

677

154

897

553

275

017

908

765

612

512

503

170

094

7-9若对有n个元素的有序顺序表和无序顺序表进行顺序搜索,试就下列三种情况分别讨论两者在等搜索概率时的平均搜索长度是否相同?

(1)搜索失败;

(2)搜索成功,且表中只有一个关键码等于给定值k的对象;

(3)搜索成功,且表中有若干个关键码等于给定值k的对象,要求一次搜索找出所有对象。

【解答】

(1)不同。

因为有序顺序表搜索到其关键码比要查找值大的对象时就停止搜索,报告失败信息,不必搜索到表尾;而无序顺序表必须搜索到表尾才能断定搜索失败。

(2)相同。

搜索到表中对象的关键码等于给定值时就停止搜索,报告成功信息。

(3)不同。

有序顺序表中关键码相等的对象相继排列在一起,只要搜索到第一个就可以连续搜索到其它关键码相同的对象。

而无序顺序表必须搜索全部表中对象才能确定相同关键码的对象都找了出来,所需时间就不相同了。

前两问可做定量分析。

第三问推导出的公式比较复杂,不再进一步讨论。

7-10假定用一个循环链表来实现一个有序表,并让指针head指向具有最小关键码的结点。

指针current初始时等于head,每次搜索后指向当前检索的结点,但如果搜索不成功则current重置为head。

试编写一个函数search(head,current,key)实现这种搜索。

当搜索成功时函数返回被检索的结点地址,若搜索不成功则函数返回空指针0。

请说明如何保持指针current以减少搜索时的平均搜索长度。

【解答】

current

60

50

40

30

20

10

head

相应的搜索函数可以定义为链表及链表结点类的友元函数,直接使用链表及链表结点类的私有数据成员。

template

ListNode*Search(ListNode*head,ListNode*¤t,Typekey){

ListNode*p,*q;

if(key

else{p=current;q=head;}

while(p!

=q&&p->datalink;//循链搜索其值等于key的结点

if(p->data==key){current=p;returnp;}//找到,返回结点地址

else{current=head;returnNULL;}//未找到,返回空指针

}

7-11考虑用双向链表来实现一个有序表,使得能在这个表中进行正向和反向搜索。

若指针p总是指向最后成功搜索到的结点,搜索可以从p指示的结点出发沿任一方向进行。

试根据这种情况编写一个函数search(head,p,key),检索具有关键码key的结点,并相应地修改p。

最后请给出搜索成功和搜索不成功时的平均搜索长度。

p

【解答】

40

70

60

50

30

20

10

head

template

DblListNode*Search(

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 财务管理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2