23.10.25 彭波数据结构第八章习题 算法设计

五、算法设计题

  1. 设计一个算法:递归折半查找给定关键字
    代码:
    int HalfSearch(SSTable T,ElemType k){
    	int high=T.length;
    	int low=1;
    	int mid=(high+low)/2;//找到中间位置 
    	if(T.r[mid].key==k) return mid;//如果是查找值与中间位置相同则返回mid 
    	else if(T.r[mid].key>k){
    		SSTable S;
    		S.length=mid-1;
    		for(int i=0;i<S.length;i++)
    			S.r[i]=T.r[i];
    		return HalfSearch(S,k);
    	}//如果k小于中间值,则将左半部分赋值给S,并递归在S中查找 
    	else{
    		S.length=T.length-mid+1;
    		for(int i=0;i<S.length;i++)
    			S.r[i]=T.r[mid+i];
    		return HalfSearch(S,k);		
    	}//如果k大于中间值,则将右半部分赋值给S,并递归在S中查找 
    	return 0;//查找失败 
    } 

  2. 设计一个算法:求给定结点在二叉排序树中所在的层数。
    代码:
    int FindLevels(BSTree T,RedType k){
    	if(T==NULL) return 0;//树空则返回0 
    	if(k==T->data) return 1;//如果根结点的值与k相等返回层数为1 
    	else if(k<T->data){//如果k小于根结点的值,则递归计算左子树 
    		int leftlev=FindLevels(T->lchild,k);
    		if(leftlev!=0)
    			return leftlev+1;//如果在左子树中找到k的层数则返回左子树中的层数值+1 
    	}else{//如果k大于根结点的值,则递归计算右子树
    		int rightlev=FindLevels(T->rchild,k);
    		if(rightlev!=0)
    			return rightlev+1;//如果在右子树中找到k的层数则返回右子树中的层数值+1
    	}
    	return 0;//树中没有值为k的结点,返回0 
    }

  3. 设计一个算法:判别给定二叉树是否为二叉排序树。设此二叉树以二叉链表为存储结构,且树中记录结点的关键字均不同。
    代码:
    bool isBST(BSTree T){
    	if(T==NULL) return TRUE;//如果T为空树,则返回TRUE 
    	if(T->lchild!=NULL&&T->lchild->data>T->data)
    		return FALSE;//如果T有左孩子且左孩子的值大于T则返回FALSE 
    	if(T->rchild!=NULL&&T->rchild->data<T->data)
    		return FALSE;//如果T有右孩子且右孩子的值小于T则返回FALSE
    	return isBST(T->lchild)&&isBST(T->rchild);//递归检查T的左右孩子 
    } 

  4. 设计一个算法:在二叉排序树上找出任意两个不同结点的最近公共祖先。
    代码:
    BSTNode *Ancestor(BSTree T,RedType k1,RedType k2){
    	BSTNode *p,*pre;
    	p=pre=T;//将p和pre都指向根结点 
    	while(p!=NULL){
    		if((k1<p->data)&&(k2<p->data)){
    			pre=p;
    			p=p->lchild;
    		}//如果k1,k2都小于p的值,则pre指向p,p指向p的左孩子 
    		else if((k1>p->data)&&(k2>p->data)){
    			pre=p;
    			p=p->rchild;
    		}//如果k1,k2都大于p的值,则pre指向p,p指向p的右孩子 
    		else if(((k1<p->data)&&(k2>p->data))||((k1>p->data)&&(k2<p->data)))
    			return p;//如果k1,k2一个比p大一个比p小,那么p就是他们的第一个公共祖先 
    		else if((k1==p->data)||(k2==p->data))
    			return pre;//如果p与k1或k2任何一个值相同,那么pre就是他们的公共祖先 
    	}
    }

  5. 假设哈希表上删除操作已将记录关键字标记为DELETED(例如设DELETED为-2)。试设计一个查找及插入算法,使之能够正确的查找插入。
    代码:
    int HashSearch_Close(HashTable T,RedType red){
    	int m=HashTable_Size;
    	int DELETED=-2; 
    	int k=-1
    	int j=Hash(red.key,m);//哈希函数,求red对应的哈希地址 
    	if(T.r[j].key==red.key) return j;//未发生冲突,一次查找成功,返回地址j 
    	int i=(j+1)%m;//开放定址法,线性探测再散列 
    	while((T.r[i].key!=NULL)&&(i!=j)){//当i处哈希表值不为空,且i与j不等时 
    		if(T.r[i].key==red.key) return i;//如果给定值与i处关键字相等,查找成功返回i 
    		if(T.r[i].key==DELETED) k=i;//如果线性探测过程中发现有删除点,做记录 
    		i=(i+1)%m;//没满足上述条件继续使用开放定址法,线性探测再散列  
    	}
    	if(i==j){
    		if(k>=0){
    			T.r[k]=red;
    			return -1;
    		}
    		else{
    			cout<<"Overflow!"<<endl;
    			exit(1);
    		}
    	}
    	/*如果最后循环到i=j都没找到,但是探测过程中有删除点,
    	则插入到所记录的删除点,否则报错溢出*/
    	else{//如果找到个位置i为空的单元 
    		T.r[i]=red;//将red插入i处 
    		T.length++;//哈希表记录个数加一 
    		return -1;//返回-1 
    	}
    } 
    int Hash(ElemType k,int m){//除留余数法求k的哈希地址 
    	return k%m;
    } 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值