PTA 6-10 二分查找 6-11 先序输出叶结点 6-12 二叉搜索树的操作集

6-10 二分查找
题目要求:
本题要求实现二分查找算法。L是用户传入的一个线性表,其中ElementType元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch要查找X在Data中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound。
代码如下:

Position BinarySearch( List L, ElementType X ){
	int head,last,mid;
	head=1;
	last=L->Last;
	while(head<=last){
		mid=(head+last)/2;
		if(L->Data[mid]==X){
			return mid;
		}
		if(L->Data[mid]>X){
			last=mid-1;
		}
		if(L->Data[mid]<X){
			head=mid+1;
		}
	}
	return NotFound;
} 

本题思路:
1、二分法查找有三个指针分别指向头、尾和中间。循环比较欲找X与中间值的大小关系,直到头尾指针重合或者中间指针指到了X上,判断X是否在数组中存在。
2、while的判断语句中while(head<=last)必须有等于号。原因是如果X在头尾指针相遇的位置,假设判断语句只有<号,此时head和last相等会跳出循环,从而没法返回这一项。

6-11 先序输出叶结点
题目要求:
本题要求按照先序遍历的顺序输出给定二叉树的叶结点。接口定义:void PreorderPrintLeaves( BinTree BT )
函数PreorderPrintLeaves应按照先序遍历的顺序输出给定二叉树BT的叶结点,格式为一个空格跟着一个字符。
代码如下:

void PreorderPrintLeaves( BinTree BT ){
	if(BT!=NULL){
		if(BT->Left==NULL && BT->Right==NULL){
			printf(" %c",BT->Data);
		}
			PreorderPrintLeaves(BT->Left);
			PreorderPrintLeaves(BT->Right);
	}
}

本题思路:
1、之前做过一道用单链表穿起叶子结点的题,比较类似,思想都差不多,这道题做了一定简化,使用递归的思想,遇到结点先判断是否为叶子结点,如果是则输出数据,之后处理非叶结点的左右子树。递归的思路是从下到上的,从最迫切需求到一般需求,需要好好体会。

6-12 二叉搜索树的操作集
题目要求:
本题要求实现给定二叉搜索树的5种常用操作。
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
函数Insert将X插入二叉搜索树BST并返回结果树的根结点指针;
函数Delete将X从二叉搜索树BST中删除,并返回结果树的根结点指针;如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
函数FindMin返回二叉搜索树BST中最小元结点的指针;
函数FindMax返回二叉搜索树BST中最大元结点的指针。
代码如下:

BinTree Insert( BinTree BST, ElementType X ){
	if(BST==NULL){  //遇到空节点。 
		BST=(BinTree)malloc(sizeof(struct TNode));
		BST->Data=X;
		BST->Left=NULL;
		BST->Right=NULL;
	}
	else{
		if(BST->Data>X){
			BST->Left=Insert(BST->Left,X);//若果不加BST->left=,会出问题。 
		} 
		else if(BST->Data<X){
			BST->Right=Insert(BST->Right,X);
		}
	}
	return BST; 
}

BinTree Delete( BinTree BST, ElementType X ){
	BinTree temp;
	if(BST==NULL){
		printf("Not Found\n");
	}
	else{
    	if(BST->Data>X){
	       BST->Left=Delete(BST->Left,X);
     	}
	    else if(BST->Data<X){
	       BST->Right=Delete(BST->Right,X);
    	}
	    else{  //找到需要删除的结点 
		   if(BST->Left && BST->Right){  //左右子树都存在 
		     	temp=FindMin(BST->Right);
			    BST->Data=temp->Data;
			    BST->Right=Delete(BST->Right,temp->Data);
	    	} 
	    	else{  //只存在单子树。 
	    		temp=BST;
	    		if(!BST->Left){
	    			BST=BST->Right;
				}
				else if(!BST->Right){
					BST=BST->Left;
				}
				free(temp);
			}
    	}
    }
    return BST;
}
Position Find( BinTree BST, ElementType X ){
	while(BST!=NULL){
		if(BST->Data==X){
			return BST;
		}
		else if(BST->Data>X){
			BST=BST->Left;
		}
		else if(BST->Data<X){
			BST=BST->Right;
		}
	}
	return NULL;
}

Position FindMin( BinTree BST ){
	if(BST==NULL){
		return NULL;
	}
	while(BST->Left!=NULL){
		BST=BST->Left;
	}
	return BST;
}

Position FindMax( BinTree BST ){
	if(BST==NULL){
		return NULL;
	}
	while(BST->Right!=NULL){
		BST=BST->Right;
	}
	return BST;
}

本题思路:
1、插入操作中:运用递归的思想,首先判断是否到达插入结点位置,到达则插入,注意要分配储存空间。之后判断遇到普通结点应该怎么做。注意因为后续会对相关联普通结点的左或右子树进行插入,如果在递归时BST->Left=Insert(BST->Left,X);没有写BST->Left=会出现新插入的结点没有父结点。
2、查找操作比较简单,比现结点大就找右子树,小就找左子树。
3、找最小操作就是找整个树上最左结点,找最大操作就是找最右结点。注意如果没有遇到相应结点或者为空树则返回NULL。
4、删除操作:采用递归的思想,如果找不到就返回没找到,之后对普通结点进行判别,依旧需要注意的是删除操作也是会对左或右子树进行更改,所以需要加BST->Left=。之后有需要判断预删除节点是左右子树都存在还是单子树。
删除需要借助一个temp变量来定位现指针,如果是左右子树都存在的情况,则需要找到右子树的最小值,与现指针指向的值进行替换,之后删除被替换的结点。
如果删除的是单子树,就子承父业。这里记得要将存储在temp里的他爹删除掉。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值