【数据结构与算法】- 查找(算法)

目录

一:写出折半查找的递归算法。初始调用时,low为1,high为ST.length

二:线性表中各个节点的检索概率不等时,可用如下 提高顺序检索的效率。若找到指定的节点,则将该节点和其前驱节点(若存在)交换,使得经常被检索的节点尽量位于表的前端,试着设计在顺序结构和链式结构的线性表上实现上述策略的顺序检索算法。

三:试着编写算法,判断给定的二叉树是否是二叉排序树

四:设计一个算法 求出指定节点在给定二叉排序树中的层次

五:利用二叉树遍历思想 编写一个判断二叉树是否是平衡二叉树的算法

六:设计一个算法,求出给定二叉排序树中最小和最大的关键字

七:设计一个算法 从大到小输出二叉排序树中所有值不小于k的关键字

八:编写一个递归算法,在一颗有n个节点的,随机建立起来的二叉排序树上查找第k(1<=k<=n)小的元素,并返回指向该节点的指针。二叉排序树中的每个节点中除了data lchild rchild等数据成员外,增加一个count成员,保存以该节点为根的子树上的节点个数


扫描二维码关注公众号,回复: 14417827 查看本文章

一:写出折半查找的递归算法。初始调用时,low为1,high为ST.length

#include <stdio.h>
#define N 5
 
int BinSerch(int s[],int low,int high,int num)
{
    int mid;
    if(low>high)
        return -1;
    else
    {
        mid=(low+high)/2;
        if(s[mid]==num)
            return mid;
        else if(s[mid]<num)
            return BinSerch(s,mid+1,high,num);
        else
            return BinSerch(s,low,mid-1,num);
    }
}
 
 
int main()
{
    int a[N],i,num,result;
    for(i=0;i<N;i++)
        scanf("%d",&a[i]);
    printf("请输入要查找的数:\n");
    scanf("%d",&num);
    result=BinSerch(a,0,N-1,num);
    if(-1!=result)
        printf("%d存在,为第%d个元素",num,result+1);
    else
        printf("查找失败");
 
    return 0;
}

二:线性表中各个节点的检索概率不等时,可用如下 提高顺序检索的效率。若找到指定的节点,则将该节点和其前驱节点(若存在)交换,使得经常被检索的节点尽量位于表的前端,试着设计在顺序结构和链式结构的线性表上实现上述策略的顺序检索算法。

#include<iostream>
using namespace std;

//置前函数
int Search(int a[],int n,int k)
{
	//遍历
	int i;
	for(i=0;i<n;i++)
	{
		if(a[i]==k) break;
	}
	//找到就交换 返回交换的位置
	if(i>0&&i<n)
	{
		int t=a[i-1];
		a[i-1]=a[i];
		a[i]=t;
		return i-1;
	}
	//没有找到 -1
	else return -1;
}

int main()
{
	int a[6]={1,2,3,4,5};
	cout<<Search(a,5,4)<<endl;
	return 0;
}

三:试着编写算法,判断给定的二叉树是否是二叉排序树

#include<iostream>
using namespace std;
//树节点的存储结构
typedef struct treenode{
    //节点的值
	char data;
	//左右孩子指针
	struct treenode *lchild,*rchild;
}treenode,*tree;

//建树 
void buildtree(tree &t)
{
	char ch;
	cin>>ch;
	if(ch == '#') t=NULL;
	else
	{
		//分配内存
		t = (treenode *)malloc(sizeof(treenode));
		//赋值
		t->data=ch;
		//初始化
		t->lchild = NULL;
		t->rchild = NULL;
		//递归去赋值
		buildtree(t->lchild);
		buildtree(t->rchild);
	}
}

//中序遍历二叉树是否是二叉排序树

//初始化前驱值
int pre = -35555;
int isok(tree t)
{
	//先判断树是否为空
	if(t==NULL) return 1;
	else
	{
		//递归求左子树是否是二叉排序树
		int b1 = isok(t->lchild);
		//判断左子树的值和当前节点与前驱节点值的比较
		if(b1==0||((t->data)-'0')<=pre) return 0;
		//当前节点作为下一个前驱节点 保存下来
		pre = (t->data)-'0';
		//递归求右子树的值
		return isok(t->rchild);
		//返回
	}
}

int main()
{
	tree t;
	buildtree(t);
	cout<<isok(t)<<endl;
	return 0;
}

/*
         F
	   E    H
	C     G   I
  A   D
    B
	FECA#B##D###HG##I##
*/

四:设计一个算法 求出指定节点在给定二叉排序树中的层次

#include<iostream>
using namespace std;
//树节点的存储结构
typedef struct treenode{
    //节点的值
	char data;
	//左右孩子指针
	struct treenode *lchild,*rchild;
}treenode,*tree;

//建树 
void buildtree(tree &t)
{
	char ch;
	cin>>ch;
	if(ch == '#') t=NULL;
	else
	{
		//分配内存
		t = (treenode *)malloc(sizeof(treenode));
		//赋值
		t->data=ch;
		//初始化
		t->lchild = NULL;
		t->rchild = NULL;
		//递归去赋值 左右子树的节点
		buildtree(t->lchild);
		buildtree(t->rchild);
	}
}

//找层次
int level(tree t,treenode *p)
{
	//层数初始化
	int n=0;
	//遍历树的节点
	treenode *tt=t;
	//树不空的话 根节点层数+1
	if(t!=NULL)
	{
		n++;
		//循环条件是当前节点的值不为要找的那个值
		while(tt->data!=p->data)
		{
			if(tt->data>p->data)//当前节点值大了 节点指向左孩子
				tt =tt->lchild;
			else tt= tt->rchild;//当前节点值小了 节点指向右孩子
			n++;//同时层数+1
		}
	}
	//最后返回层数
	return n;
}

int main()
{
	tree t;
	buildtree(t);
	cout<<level(t,t->lchild->lchild->lchild->rchild)<<endl;
	return 0;
}

/*
         F
	   E    H
	C     G   I
  A   D
    B
	FECA#B##D###HG##I##
*/

五:利用二叉树遍历思想 编写一个判断二叉树是否是平衡二叉树的算法

#include<iostream>

using namespace std;

int max(int x, int y)
{
   int z;
   if (x > y)
    z = x;
   else z = y;
    return z;
}

//树节点的存储结构
typedef struct treenode{
    //节点的值
	char data;
	//左右孩子指针
	struct treenode *lchild,*rchild;
}treenode,*tree;

//建树 
void buildtree(tree &t)
{
	char ch;
	cin>>ch;
	if(ch == '#') t=NULL;
	else
	{
		//分配内存
		t = (treenode *)malloc(sizeof(treenode));
		//赋值
		t->data=ch;
		//初始化
		t->lchild = NULL;
		t->rchild = NULL;
		//递归去赋值 左右子树的节点
		buildtree(t->lchild);
		buildtree(t->rchild);
	}
}

//后序遍历 判断是否是平衡二叉树
void isAVL(tree t,int &ba,int &h)
{
	//左右子树的高度 平衡因子变量
	int h1,h2,b1,b2;
	//空树 高度为0 平衡因子为1
	if(t==NULL)
	{
		h = 0;
		ba = 1;
	}
	//只有一个根节点 高度为1 平衡因子为1
	else if(t->lchild==NULL&&t->rchild==NULL)
	{
		h= 1;
		ba = 1;
	}
	else
	{
		//递归判断左子树
        isAVL(t->lchild,ba,h);
	     //递归判断右子树
        isAVL(t->rchild,ba,h);
		//到根这里 更新树高
		h = max(h1,h2)+1;
		//判断左右子树高度绝对值之差
		if(abs(h1-h2)<=1)
		{
		    ba = b1&&b2;	
		}
		//判断左右子树平衡因子
		else ba = 0;

	}
}


int main()
{
	tree t;
	buildtree(t);
    int ba,h;
    isAVL(t,ba,h);
	cout<<ba<<endl;
	return 0;
}

/*
         F
	   E    H
	C     G   I
  A   D
    B
	FECA#B##D###HG##I##
*/

六:设计一个算法,求出给定二叉排序树中最小和最大的关键字

#include<iostream>

using namespace std;

//树节点的存储结构
typedef struct treenode{
    //节点的值
	char data;
	//左右孩子指针
	struct treenode *lchild,*rchild;
}treenode,*tree;

//建树 
void buildtree(tree &t)
{
	char ch;
	cin>>ch;
	if(ch == '#') t=NULL;
	else
	{
		//分配内存
		t = (treenode *)malloc(sizeof(treenode));
		//赋值
		t->data=ch;
		//初始化
		t->lchild = NULL;
		t->rchild = NULL;
		//递归去赋值 左右子树的节点
		buildtree(t->lchild);
		buildtree(t->rchild);
	}
}

//二叉排序树中最小关键字
char Min(tree t)
{
	while(t->lchild!=NULL)
	{
		t=t->lchild;
	}
	return  t->data;
}

//二叉排序树中最大关键字
char Max(tree t)
{
	while(t->rchild!=NULL)
	{
		t=t->rchild;
	}
	return  t->data;
}

int main()
{
	tree t;
	buildtree(t);
    cout<<Min(t)<<endl;
	cout<<Max(t)<<endl;
	return 0;
}

/*
         F
	   E    H
	C     G   I
  A   D
    B
	FECA#B##D###HG##I##
*/

七:设计一个算法 从大到小输出二叉排序树中所有值不小于k的关键字

#include<iostream>
using namespace std;

//树节点的存储结构
typedef struct treenode{
    //节点的值
	char data;
	//左右孩子指针
	struct treenode *lchild,*rchild;
}treenode,*tree;

//建树 
void buildtree(tree &t)
{
	char ch;
	cin>>ch;
	if(ch == '#') t=NULL;
	else
	{
		//分配内存
		t = (treenode *)malloc(sizeof(treenode));
		//赋值
		t->data=ch;
		//初始化
		t->lchild = NULL;
		t->rchild = NULL;
		//递归去赋值 左右子树的节点
		buildtree(t->lchild);
		buildtree(t->rchild);
	}
}

//输出>=k的关键字
void disp(tree t,char k)
{
	//空树
	if(t==NULL) return;
	//右子树
	if(t->rchild!=NULL)
	{
		disp(t->rchild,k);
	}
	//根输出 
	if(t->data>=k) cout<<t->data<<""<<endl;
	//左子树
	if(t->lchild!=NULL)
		disp(t->lchild,k);
}

int main()
{
	tree t;
	buildtree(t);
    disp(t,'E');
	return 0;
}

/*
         F
	   E    H
	C     G   I
  A   D
    B
	FECA#B##D###HG##I##
*/

八:编写一个递归算法,在一颗有n个节点的,随机建立起来的二叉排序树上查找第k(1<=k<=n)小的元素,并返回指向该节点的指针。二叉排序树中的每个节点中除了data lchild rchild等数据成员外,增加一个count成员,保存以该节点为根的子树上的节点个数

核心代码

//树节点的存储结构
typedef struct treenode{
    //节点的值
	char data;
	//左右孩子指针
	struct treenode *lchild,*rchild;
	//子树包括根的所有节点个数
	int count;
}treenode,*tree;

//第k小元素
treenode *min_k(tree t,int k)
{
	//k合法条件
	if(k<1||k>t->count) return NULL;
	//左子树空的情况
	if(t->lchild==NULL)
	{
		//k=1 就是根节点
		if(k==1) return t;
		//k不为1 就是到右子树中找第k-1小 根节点已考虑
		else min_k(t->rchild,k-1);
	}

	//左子树不为空
	else
	{
		//左子树节点个数为k-1 结果就是根节点
		if(t->lchild->count==k-1) return t;
		//左子树节点个数>k-1 在左子树中找第k小
		if(t->lchild->count>k-1) return min_k(t->lchild,k);
		//左子树节点个数<k-1 在右子树中找第k-(左子树节点个数)小的元素
		if(t->lchild->count<k-1) return min_k(t->rchild,k-(t->lchild->count+1));
	}
}

猜你喜欢

转载自blog.csdn.net/m0_56051805/article/details/125942418