第九章 查找Word格式.docx

上传人:b****6 文档编号:19686627 上传时间:2023-01-08 格式:DOCX 页数:11 大小:20.51KB
下载 相关 举报
第九章 查找Word格式.docx_第1页
第1页 / 共11页
第九章 查找Word格式.docx_第2页
第2页 / 共11页
第九章 查找Word格式.docx_第3页
第3页 / 共11页
第九章 查找Word格式.docx_第4页
第4页 / 共11页
第九章 查找Word格式.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

第九章 查找Word格式.docx

《第九章 查找Word格式.docx》由会员分享,可在线阅读,更多相关《第九章 查找Word格式.docx(11页珍藏版)》请在冰豆网上搜索。

第九章 查找Word格式.docx

=high)

if(key>

=r[mid].key&

&

key<

r[mid+1].key)//查找结束的条件

returnmid;

elseif(key<

r[mid].key)high=mid;

elselow=mid;

}//本算法不存在查找失败的情况,不需要return0;

}//Locate_Bin

9.28

typedefstruct{

 

intmaxkey;

intfirstloc;

}Index;

int*elem;

intlength;

Indexidx[MAXBLOCK];

//每块起始位置和最大元素,其中idx[0]不利用,其内容初始化为{0,0}以利于折半查找

intblknum;

//块的数目

}IdxSqList;

//索引顺序表类型

intSearch_IdxSeq(IdxSqListL,intkey)//分块查找,用折半查找法确定记录所在块,块内采用顺序查找法

L.idx[L.blknum].maxkey)returnERROR;

//超过最大元素

high=L.blknum;

found=0;

=high&

!

found)//折半查找记录所在块号mid

=L.idx[mid].maxkey&

key>

L.idx[mid-1].maxkey)

found=1;

L.idx[mid].maxkey)

low=mid+1;

elsehigh=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<

i)returnERROR;

//未找到

returnk;

}//Search_IdxSeq

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

9.29

LNode*h;

//h指向最小元素

LNode*t;

//t指向上次查找的结点

}CSList;

LNode*Search_CSList(CSList&

L,intkey)//在有序单循环链表存储结构上的查找算法,假定每次查找都成功

if(L.t->

data==key)returnL.t;

elseif(L.t->

data>

for(p=L.h,i=1;

p->

data!

p=p->

next,i++);

else

for(p=L.t,i=L.tpos;

L.t=p;

//更新t指针

returnp;

}//Search_CSList

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

9.30

DLNode*pre;

intdata;

DLNode*next;

}DLNode;

DLNode*sp;

}DSList;

//供查找的双向循环链表类型

DLNode*Search_DSList(DSList&

L,intkey)//在有序双向循环链表存储结构上的查找算法,假定每次查找都成功

p=L.sp;

if(p->

while(p->

key)p=p->

pre;

L.sp=p;

elseif(p->

data<

next;

}//Search_DSList

本题的平均查找长度与上一题相同,也是n/3.

9.31

intlast=0,flag=1;

intIs_BSTree(BitreeT)//判断二叉树T是否二叉排序树,是则返回1,否则返回0

if(T->

lchild&

flag)Is_BSTree(T->

lchild);

last)flag=0;

//与其中序前驱相比较

last=T->

data;

rchild&

rchild);

returnflag;

}//Is_BSTree

9.32

intlast=0;

voidMaxLT_MinGT(BiTreeT,intx)//找到二叉排序树T中小于x的最大元素和大于x的最小元素

lchild)MaxLT_MinGT(T->

lchild,x);

//本算法仍是借助中序遍历来实现

if(last<

x&

T->

=x)//找到了小于x的最大元素

printf("

a=%d\n"

last);

=x&

x)//找到了大于x的最小元素

b=%d\n"

T->

data);

rchild)MaxLT_MinGT(T->

rchild,x);

}//MaxLT_MinGT

9.33

voidPrint_NLT(BiTreeT,intx)//从大到小输出二叉排序树T中所有不小于x的元素

rchild)Print_NLT(T->

x)exit();

//当遇到小于x的元素时立即结束运行

%d\n"

lchild)Print_NLT(T->

//先右后左的中序遍历

}//Print_NLT

9.34

voidDelete_NLT(BiTree&

T,intx)//删除二叉排序树T中所有不小于x元素结点,并释放空间

rchild)Delete_NLT(T->

q=T;

T=T->

lchild;

free(q);

//如果树根不小于x,则删除树根,并以左子树的根作为新的树根

if(T)Delete_NLT(T,x);

//继续在左子树中执行算法

}//Delete_NLT

9.35

voidPrint_Between(BiThrTreeT,inta,intb)//打印输出后继线索二叉排序树T中所有大于a且小于b的元素

p=T;

while(!

ltag)p=p->

//找到最小元素

while(p&

b)

a)printf("

p->

//输出符合条件的元素

rtag)p=p->

rtag;

rchild;

}//转到中序后继

}//while

}//Print_Between

9.36

voidBSTree_Insert_Key(BiThrTree&

T,intx)//在后继线索二叉排序树T中插入元素x

x)//插入到右侧

rtag)//T没有右子树时,作为右孩子插入

p=T->

q=(BiThrNode*)malloc(sizeof(BiThrNode));

q->

data=x;

rchild=q;

rtag=0;

rtag=1;

rchild=p;

//修改原线索

elseBSTree_Insert_Key(T->

//T有右子树时,插入右子树中

}//if

elseif(T->

x)//插入到左子树中

if(!

lchild)//T没有左子树时,作为左孩子插入

lchild=q;

rchild=T;

//修改自身的线索

//T有左子树时,插入左子树中

}//BSTree_Insert_Key

9.37

StatusBSTree_Delete_key(BiThrTree&

T,intx)//在后继线索二叉排序树T中删除元素x

BTNode*pre,*ptr,*suc;

//ptr为x所在结点,pre和suc分别指向ptr的前驱和后继

last=NULL;

//last始终指向当前结点p的前一个(前驱)

//找到中序起始元素

while(p)

data==x)//找到了元素x结点

pre=last;

ptr=p;

elseif(last&

last->

data==x)suc=p;

//找到了x的后继

last=p;

}//while//借助中序遍历找到元素x及其前驱和后继结点

ptr)returnERROR;

//未找到待删结点

Delete_BSTree(ptr);

//删除x结点

if(pre&

pre->

rtag)

rchild=suc;

//修改线索

returnOK;

}//BSTree_Delete_key

voidDelete_BSTree(BiThrTree&

T)//课本上给出的删除二叉排序树的子树T的算法,按照线索二叉树的结构作了一些改动

ltag&

rtag)//结点无右子树,此时只需重接其左子树

rtag)//结点无左子树,此时只需重接其右子树

elseif(!

rtag)//结点既有左子树又有右子树

r=T->

r->

s=r;

r=r->

//找到结点的前驱r和r的双亲s

data=r->

//用r代替T结点

if(s!

=T)

s->

rchild=r->

elses->

lchild=r->

//重接r的左子树到其双亲结点上

q=r;

}//else

//删除结点

}//Delete_BSTree

本算法采用了先求出x结点的前驱和后继,再删除x结点的办法,这样修改线索时会比较简单,直接让前驱的线索指向后继就行了.如果试图在删除x结点的同时修改线索,则问题反而复杂化了.

9.38

voidBSTree_Merge(BiTree&

T,BiTree&

S)//把二叉排序树S合并到T中

if(S->

lchild)BSTree_Merge(T,S->

rchild)BSTree_Merge(T,S->

//合并子树

Insert_Key(T,S);

//插入元素

}//BSTree_Merge

voidInsert_Node(Bitree&

T,BTNode*S)//把树结点S插入到T的合适位置上

data)

rchild)T->

rchild=S;

elseInsert_Node(T->

rchild,S);

elseif(S->

lchild)T->

lchild=S;

lchild,S);

S->

lchild=NULL;

//插入的新结点必须和原来的左右子树断绝关系

rchild=NULL;

//否则会导致树结构的混乱

}//Insert_Node

这是一个与课本上不同的插入算法.在合并过程中,并不释放或新建任何结点,而是采取修改指针的方式来完成合并.这样,就必须按照后序序列把一棵树中的元素逐个连接到另一棵树上,否则将会导致树的结构的混乱.

9.39

voidBSTree_Split(BiTree&

A,BiTree&

B,intx)//把二叉排序树T分裂为两棵二叉排序树A和B,其中A的元素全部小于等于x,B的元素全部大于x

lchild)BSTree_Split(T->

lchild,A,B,x);

rchild)BSTree_Split(T->

rchild,A,B,x);

//分裂左右子树

=x)Insert_Node(A,T);

elseInsert_Node(B,T);

//将元素结点插入合适的树中

}//BSTree_Split

T)T=S;

//考虑到刚开始分裂时树A和树B为空的情况

data)//其余部分与上一题同

}//Insert_Key

9.40

intbf;

intlsize;

//lsize域表示该结点的左子树的结点总数加1

BlcNode*lchild,*rchild;

}BlcNode,*BlcTree;

//含lsize域的平衡二叉排序树类型

BTNode*Locate_BlcTree(BlcTreeT,intk)//在含lsize域的平衡二叉排序树T中确定第k小的结点指针

T)returnNULL;

//k小于1或大于树结点总数

lsize==k)returnT;

//就是这个结点

lsize>

k)

returnLocate_BlcTree(T->

lchild,k);

//在左子树中寻找

elsereturnLocate_BlcTree(T->

rchild,k-T->

lsize);

//在右子树中寻找,注意要修改k的值

}//Locate_BlcTree

9.41

enum{LEAF,BRANCH}tag;

//结点类型标识

intkeynum;

BPLinkparent;

//双亲指针

intkey[MAXCHILD];

//关键字

union{

BPLinkchild[MAXCHILD];

//非叶结点的孩子指针

struct{

rectype*info[MAXCHILD];

//叶子结点的信息指针

BPNode*next;

//指向下一个叶子结点的链接

}leaf;

}

}BPNode,*BPLink,*BPTree;

//B+树及其结点类型

StatusBPTree_Search(BPTreeT,intkey,BPNode*ptr,intpos)//B+树中按关键字随机查找的算法,返回包含关键字的叶子结点的指针ptr以及关键字在叶子结点中的位置pos

while(p.tag==BRANCH)//沿分支向下查找

for(i=0;

i<

keynum&

key[i];

//确定关键字所在子树

if(i==p->

keynum)returnERROR;

//关键字太大

child[i];

key!

=p->

//在叶子结点中查找

//找不到关键字

pos=i;

}//BPTree_Search 

9.42

voidTrieTree_Insert_Key(TrieTree&

T,StringTypekey)//在Trie树T中插入字符串key,StringType的结构见第四章

q=(TrieNode*)malloc(sizeof(TrieNode));

kind=LEAF;

lf.k=key;

//建叶子结点

klen=key[0];

i=1;

=klen&

bh.ptr[ord(key[i])])

bh.ptr[ord(key[i])];

i++;

}//自上而下查找

kind==BRANCH)//如果最后落到分支结点(无同义词):

bh.ptr[o

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1