数据结构⑤:查找操作

一、要求:

(1)随机产生n个互不相同的两位整数,构造一个查找表。

(2)输入一个整数,利用顺序查找法在查找表中查找该整数是否存在。若查找成功,返回该整数在表中的位置;查找失败则返回0。

(3)对查找表按递增顺序进行排序。

(4)输入一个整数,利用折半查找法在有序表中查找该整数是否存在。若查找成功,返回该整数在表中的位置;查找失败则返回0。

(5)输入互不相同的一组整数,构造一棵二叉排序树,要求:
 ① 按递减有序的顺序输出;
 ② 输入一个整数,查找该整数是否在该二叉排序树中,查找成功返回1,否则返回0;
 ③ 在②中,若查找成功,则将该结点从二叉排序树中删除。

二、思路:

①随机产生10~20个不同的两位整数,可利用srand(time(NULL))产生随机数。

②利用顺序查找法查找时,从查找表的后面向前查找,若得到的最后的关键字值等于key的记录的位置为0,说明查找失败,否则查找成功。

③对查找表排序可利用冒泡排序法。

④折半查找:在有序表中,首先选取表中间记录的关键字与给定值进行比较。若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半子表中继续查找;若给定值大于中间记录的关键字,则在中间记录的右半子表中继续查找。重复上述过程,直至查找成功;或当前的查找区间无记录,则查找失败。

⑤若按递减有序的顺序输出二叉排序树,则需建立逆二叉排序树;

⑥建立二叉排序树的过程就是从空树开始,不断向二叉排序树中插入结点的过程。

⑦二叉排序树的查找,若二叉排序树为空,则查找失败。若非空,则将给定值与根结点的关键字进行比较:
  若给定值与根结点的关键字相同,则查找成功。
  若给定值小于根结点的关键字,则在根结点的左子树上查找。
  若给定值大于根结点的关键字,则在根结点的右子树上查找。

⑧二叉树的插入:
 若在二叉排序树中查找失败,则为关键字key申请新结点,并将该结点插到插到二叉排序树中合适的位置处。
 若二叉排序树为空,则为待插入关键字key申请结点,并作为根结点插入。
 若二叉排序树非空,则将关键字key与根结点的关键字的值进行比较:
  若key=bst->data.key,查找成功,无需插入;
  若keydata.key,沿左子树查找,若查找失败,将新结点插到合适的位置处。
  若key>bst->data.key,沿右子树查找,若查找失败,将新结点插到合适的位置处。

三、代码:

(1),(2),(3),(4):

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define MAX 100  //查找表大小

typedef struct{   //查找表的数据元素的类型定义
	int key;   //关键字的类型
}Elemtype;

typedef struct{  //查找表的类型定义
	Elemtype elem[MAX+1];
	int length;
}SSTable;

void Create(SSTable &ST){  //建立查找表
	int i,j,k,m;
	srand(time(NULL));
	m = rand();
	while(m<10 || m>20)
		m = rand()%20;    //随机产生10--20个两位整数
	printf("随机产生%d个两位整数:",m);
	ST.length = m+1;
	srand(time(NULL));
	for(i=1;i<=m;i++){
		k = rand()%90+10;
		j=1;
		while(j<i && k!=ST.elem[j].key){j++;}  //检验新生成的随机数是否与前面生成的随机数相同
		if(j<i)
			{ i--;	continue;} //若相同,则重新生成k
		else
			ST.elem[i].key = k; 
	}//for
}
void PrintST(SSTable ST){
	//输出查找表
	int i;
	for(i=1;i<ST.length;i++)
		printf("%3d",ST.elem[i].key);
	printf("\n");
}
int Search_Seq(SSTable ST,int key){
	//在查找表ST中查找关键字为key的记录
	int i;
	ST.elem[0].key = key;
	i = ST.length;
	while(ST.elem[i].key != key)
		i--;
	return i;
}
void Sort_ST(SSTable &ST){
	//对查找表按递增顺序进行排序
	int i,j,t;
	for(i=1;i<ST.length;i++)
		for(j=1;j<ST.length-i;j++)
			if(ST.elem[j].key>ST.elem[j+1].key){
				t = ST.elem[j].key;
				ST.elem[j].key = ST.elem[j+1].key;
				ST.elem[j+1].key = t;
			}//if
}
int Search_Bin(SSTable ST,int key){
	//在有序表ST中折半查找关键字为key的元素
	int low,high,mid;
	low = 1; high = ST.length;
	while(low<=high){
		mid = (low+high)/2;
		if(key == ST.elem[mid].key)
			return mid;
		else if(key<ST.elem[mid].key)
			high = mid-1;
		else
			low = mid +1;
	}//while
	return 0;
}
void main(){
	int f1,f2,L1,L2;
	SSTable ST;
	Create(ST);
	PrintST(ST);
	printf("请输入要用顺序查找法查找的元素:");
	scanf("%d",&f1);
	L1 = Search_Seq(ST,f1); //顺序查找法
	if(L1 == 0)
		printf("%d不存在!\n",f1);
	else
		printf("%d的位置为%d\n",f1,L1);
	Sort_ST(ST);     //排序
	printf("排序后查找表为:");
	PrintST(ST);
	printf("请输入要用折半查找法查找的元素:");
	scanf("%d",&f2);
	L2 = Search_Bin(ST,f2);   //折半查找法
	if(L2 == 0)
		printf("%d不存在!\n",L2);
	else
		printf("%d的位置为%d\n",f2,L2);
}

结果:
在这里插入图片描述

(5)二叉排序树:

#include<stdio.h>
#include<stdlib.h>

typedef struct{		//查找表的数据元素的类型定义 
	int key;		//关键字的类型
}Elemtype;

typedef struct BiTNode{     //二叉树
	Elemtype data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//typedef BiTree BT;
int SearchBST(BiTree bst,int key,BiTree &p){
	//在二叉排序树bst中查找关键字等于key的数据元素,若查找成功,p指向查找成功的结点,否则p指向查找过程中最后访问的结点
	BiTree s,f;
	s=bst;	f=NULL;
	if(!s)	{p = f; return 0;}	//空树,查找失败
	while(s!=NULL)
		if(key == s->data.key){  //查找成功
			p=s; return 1;}
		else if(key > s->data.key){
			f=s;s=s->lchild;}    //进入左子树
		else{
			f=s;s=s->rchild;}    //右子树
	p=f; return 0;
}
void InsertBST(BiTree &bst,Elemtype e){
	//在二叉排序树中插入元素e
	BiTree s,p;
	if(bst == NULL){    //空树,新结点作为根
		bst = (BiTree)malloc(sizeof(BiTNode));
		bst->data = e;
		bst->lchild = bst->rchild = NULL;
	}
	else{
		if(!SearchBST(bst,e.key,p)){   //未查到
			s = (BiTree)malloc(sizeof(BiTNode));
			s->data = e;
			s->lchild = s->rchild = NULL;
			if(e.key>p->data.key)
				p->lchild = s;
			else
				p->rchild = s;
		}//if
	}//else
}

void InOrderTraverse(BiTree bst){
	if(bst){  //中序遍历二叉排序树
		InOrderTraverse(bst->lchild);
		printf("%3d",bst->data);
		InOrderTraverse(bst->rchild);
	}
}
void CreateBST(BiTree &bst){
	//根据输入的整数,建立一棵  逆二叉排序树
	Elemtype x;	BiTree p;
	bst = NULL;
	printf("请输入一组互不相同的整数:");
	scanf("%d",&x.key);
	while(x.key!=0){   //输入0表示结束
		if(!SearchBST(bst,x.key,p))
			InsertBST(bst,x);
		scanf("%d",&x.key);
	}
}
void DeleteNode(BiTree &bst,int key){
	//在二叉排序树bst中删除值为key的结点,是bst仍保持其有序性
	BiTree p,f,q,s,pc;
	p = bst;  f=NULL;     //f为双亲结点
	while(p && p->data.key!=key){  //在bst中查找被删结点
		f=p;
		if(p->data.key < key) 
			p = p->lchild;
		else
			p = p->rchild;
	}//while
	if(!p){
		printf("该树中没有所需删除的结点\n");
		return ;
	}//if
	if(p->lchild && p->rchild){
		q=p;  s=p->rchild;
		while(s->lchild){
			q=s;   s=s->lchild;
		}//while
		p->data = s->data;
		if(q==p)	q->rchild = s->rchild;
		else q->lchild = s->rchild;
		free(s);
	}//if
	else{
		if(p->lchild)	pc = p->lchild;	//被删结点只有左子树
		else	pc = p->rchild;			//只有右子树
		if(!f)	bst = pc;				//被删结点为根结点
		else if(f->lchild = p)			//被删结点是其双亲的左孩子
			f->lchild = pc;
		else f->rchild = pc;			//右孩子或叶子
		free(p);
	}//else
}
void main(){
	int f,L;
	BiTree bst,p;
	CreateBST(bst);
	printf("逆序输出二叉排序树:");
	InOrderTraverse(bst);
	printf("\n");
	printf("请输入要查找的整数:");
	scanf("%d",&f);
	L=	SearchBST(bst,f,p);
	if(L==1){
		printf("查找成功!\n");
		DeleteNode(bst,f);
		printf("删除后逆序输出二叉排序树:");
		InOrderTraverse(bst);
		printf("\n");
	}
	else
		printf("该数不在二叉排序树中!\n");
}

结果:
在这里插入图片描述


Directions:
 仅代表初识数据结构时思路。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,您的问题是关于数据结构中的二叉树操作和应用。以下是对您提出的问题的回答: 1. 创建二叉树:二叉树可以通过递归或迭代的方式进行创建。递归创建的方法是先构建根节点,然后分别递归创建左子树和右子树;迭代创建的方法是通过队列来实现,先将根节点入队,然后出队并创建其左右子树节点并入队,直到队列为空。 2. 遍历二叉树:二叉树的遍历有三种方式,分别是先序遍历、中序遍历和后序遍历。先序遍历是先访问根节点,然后递归遍历左子树和右子树;中序遍历是先递归遍历左子树,然后访问根节点,最后递归遍历右子树;后序遍历是先递归遍历左子树和右子树,最后访问根节点。 3. 计算叶子结点个数及树的深度:计算叶子结点个数可以通过递归的方式来实现,对于每个节点,如果它是叶子节点,则返回1,否则返回它左子树和右子树的叶子节点个数之和。计算树的深度也可以通过递归的方式来实现,对于每个节点,如果它是叶子节点,则返回0,否则返回它左右子树深度的较大值加1。 4. 查找指定结点的双亲:可以通过递归查找的方式来实现,对于每个节点,如果它的左子树或右子树是目标节点,则返回该节点;否则递归查找其左子树和右子树,直到找到目标节点。 5. 查找指定结点的兄弟:可以通过递归查找的方式来实现,对于每个节点,如果它的左子树和右子树中有一个是目标节点,则返回另一个节点;否则递归查找其左子树和右子树,直到找到目标节点或者到达叶子节点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cloudcodes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值