1、=high)if(key=rmid.key&keyrmid+1.key) /查找结束的条件return mid;else if(keyL.idxmid-1.maxkey)found=1;L.idxmid.maxkey)low=mid+1;else high=mid-1;i=L.idxmid.firstloc; /块的下界j=i+blksize-1; /块的上界temp=L.elemi-1; /保存相邻元素L.elemi-1=key; /设置监视哨for(k=j;L.elemk!=key;k-); /顺序查找L.elemi-1=temp; /恢复元素if(kdata=key) return L.
2、t;else if(L.t-datafor(p=L.h,i=1;p-data!p=p-next,i+);elsefor(p=L.t,i=L.tpos;L.t=p; /更新t指针return p;/Search_CSList由于题目中假定每次查找都是成功的,所以本算法中没有关于查找失败的处理.由微积分可得,在等概率情况下,平均查找长度约为n/3. 9.30 DLNode *pre; int data; DLNode *next; DLNode; DLNode *sp; DSList; /供查找的双向循环链表类型 DLNode *Search_DSList(DSList &L,int key)/在
3、有序双向循环链表存储结构上的查找算法,假定每次查找都成功p=L.sp;if(p-while(p-key) p=p-pre;L.sp=p;else if(p-datalchild&flag) Is_BSTree(T-lchild);last) flag=0; /与其中序前驱相比较last=T-data;rchild&rchild);return flag;/Is_BSTree 9.32 int last=0;void MaxLT_MinGT(BiTree T,int x)/找到二叉排序树T中小于x的最大元素和大于x的最小元素lchild) MaxLT_MinGT(T-lchild,x); /本算
4、法仍是借助中序遍历来实现if(last=x) /找到了小于x的最大元素printf(a=%dn,last);=x&x) /找到了大于x的最小元素b=%dn,T-data);rchild) MaxLT_MinGT(T-rchild,x);/MaxLT_MinGT 9.33 void Print_NLT(BiTree T,int x)/从大到小输出二叉排序树T中所有不小于x的元素rchild) Print_NLT(T-x) exit(); /当遇到小于x的元素时立即结束运行%dnlchild) Print_NLT(T- /先右后左的中序遍历/Print_NLT 9.34 void Delete_N
5、LT(BiTree &T,int x)/删除二叉排序树T中所有不小于x元素结点,并释放空间rchild) Delete_NLT(T-q=T;T=T-lchild;free(q); /如果树根不小于x,则删除树根,并以左子树的根作为新的树根if(T) Delete_NLT(T,x); /继续在左子树中执行算法/Delete_NLT 9.35 void Print_Between(BiThrTree T,int a,int b)/打印输出后继线索二叉排序树T中所有大于a且小于b的元素p=T;while(!ltag) p=p- /找到最小元素while(p&b)a) printf(,p- /输出符合
6、条件的元素rtag) p=p-rtag;rchild; /转到中序后继/while/Print_Between 9.36 void BSTree_Insert_Key(BiThrTree &T,int x)/在后继线索二叉排序树T中插入元素xx) /插入到右侧rtag) /T没有右子树时,作为右孩子插入p=T-q=(BiThrNode*)malloc(sizeof(BiThrNode);q-data=x;rchild=q;rtag=0;rtag=1;rchild=p; /修改原线索else BSTree_Insert_Key(T-/T有右子树时,插入右子树中/ifelse if(T-x) /插
7、入到左子树中if(!lchild) /T没有左子树时,作为左孩子插入lchild=q;rchild=T; /修改自身的线索/T有左子树时,插入左子树中/BSTree_Insert_Key 9.37 Status BSTree_Delete_key(BiThrTree &T,int x)/在后继线索二叉排序树T中删除元素xBTNode *pre,*ptr,*suc;/ptr为x所在结点,pre和suc分别指向ptr的前驱和后继last=NULL; /last始终指向当前结点p的前一个(前驱) /找到中序起始元素while(p)data=x) /找到了元素x结点pre=last;ptr=p;els
8、e if(last&last-data=x) suc=p; /找到了x的后继last=p;/while /借助中序遍历找到元素x及其前驱和后继结点ptr) return ERROR; /未找到待删结点Delete_BSTree(ptr); /删除x结点if(pre&pre-rtag)rchild=suc; /修改线索return OK;/BSTree_Delete_key void Delete_BSTree(BiThrTree &T)/课本上给出的删除二叉排序树的子树T的算法,按照线索二叉树的结构作了一些改动ltag&rtag) /结点无右子树,此时只需重接其左子树rtag) /结点无左子树
9、,此时只需重接其右子树else if(!rtag) /结点既有左子树又有右子树r=T-r-s=r;r=r- /找到结点的前驱r和r的双亲sdata=r- /用r代替T结点if(s!=T)s-rchild=r-else s-lchild=r- /重接r的左子树到其双亲结点上q=r;/else /删除结点/Delete_BSTree本算法采用了先求出x结点的前驱和后继,再删除x结点的办法,这样修改线索时会比较简单,直接让前驱的线索指向后继就行了.如果试图在删除x结点的同时修改线索,则问题反而复杂化了. 9.38 void BSTree_Merge(BiTree &T,BiTree &S)/把二叉排
10、序树S合并到T中if(S-lchild) BSTree_Merge(T,S-rchild) BSTree_Merge(T,S- /合并子树Insert_Key(T,S); /插入元素/BSTree_Merge void Insert_Node(Bitree &T,BTNode *S)/把树结点S插入到T的合适位置上data)rchild) T-rchild=S;else Insert_Node(T-rchild,S);else if(S-lchild) T-lchild=S;lchild,S);S-lchild=NULL; /插入的新结点必须和原来的左右子树断绝关系rchild=NULL; /
11、否则会导致树结构的混乱/Insert_Node这是一个与课本上不同的插入算法.在合并过程中,并不释放或新建任何结点,而是采取修改指针的方式来完成合并.这样,就必须按照后序序列把一棵树中的元素逐个连接到另一棵树上,否则将会导致树的结构的混乱. 9.39 void BSTree_Split(BiTree &A,BiTree &B,int x)/把二叉排序树T分裂为两棵二叉排序树A和B,其中A的元素全部小于等于x,B的元素全部大于xlchild) BSTree_Split(T-lchild,A,B,x);rchild) BSTree_Split(T-rchild,A,B,x); /分裂左右子树=x)
12、 Insert_Node(A,T);else Insert_Node(B,T); /将元素结点插入合适的树中/BSTree_Split T) T=S; /考虑到刚开始分裂时树A和树B为空的情况data) /其余部分与上一题同/Insert_Key 9.40 int bf; int lsize; /lsize域表示该结点的左子树的结点总数加1 BlcNode *lchild,*rchild; BlcNode,*BlcTree; /含lsize域的平衡二叉排序树类型 BTNode *Locate_BlcTree(BlcTree T,int k)/在含lsize域的平衡二叉排序树T中确定第k小的结点
13、指针T) return NULL; /k小于1或大于树结点总数lsize=k) return T; /就是这个结点lsizek)return Locate_BlcTree(T-lchild,k); /在左子树中寻找else return Locate_BlcTree(T-rchild,k-T-lsize); /在右子树中寻找,注意要修改k的值/Locate_BlcTree 9.41 enum LEAF,BRANCH tag; /结点类型标识 int keynum; BPLink parent; /双亲指针 int keyMAXCHILD; /关键字 union BPLink childMAXC
14、HILD;/非叶结点的孩子指针 struct rectype *infoMAXCHILD;/叶子结点的信息指针BPNode *next; /指向下一个叶子结点的链接 leaf; BPNode,*BPLink,*BPTree;/B+树及其结点类型 Status BPTree_Search(BPTree T,int key,BPNode *ptr,int pos)/B+树中按关键字随机查找的算法,返回包含关键字的叶子结点的指针ptr以及关键字在叶子结点中的位置poswhile(p.tag=BRANCH) /沿分支向下查找for(i=0;ikeynum) return ERROR; /关键字太大ch
15、ildi;key!=p- /在叶子结点中查找 /找不到关键字pos=i;/BPTree_Search9.42 void TrieTree_Insert_Key(TrieTree &T,StringType key)/在Trie树T中插入字符串key,StringType的结构见第四章q=(TrieNode*)malloc(sizeof(TrieNode);kind=LEAF;lf.k=key; /建叶子结点klen=key0;i=1;=klen&bh.ptrord(keyi)bh.ptrord(keyi);i+; /自上而下查找kind=BRANCH) /如果最后落到分支结点(无同义词):bh.ptro
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1