C / C++ 数据结构与算法(查找)

只是我自己看书、视频的总结 可能不适合其他人看。

查找表:是由同一类型的数据元素(或记录)构成的集合。
关键字:是数据元素中某个数据项的值,也称为键值
查找,就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素或记录

静态查找表:只作查找操作的查找表。主要操作有:

  1. 查询某个“特定的”数据元素是否在查找表中。
  2. 检索某个“特定的”数据元素和各种属性。

动态查找表:在查找过程中同事插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。 主要操作有:

  1. 查找时插入数据元素。
  2. 查找时删除数据元素。

顺序表查找

对线性表进行查找操作,就是静态查找
顺序查找:又叫线性查找。
过程:从表中第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则成功。
代码:

/*顺序查找,a为数组,n为要查找的数组个数,key为要查找的关键字*/
int Sequenttial_Search (int *a,int n, int key)
{
	int i;
	for(i=1;i<=n;i++)
		{
			if (a[i]==key)
				return i;
		}
	return 0;
}

有序表查找

折半查找

折半查找:二分法。前提是线性表中的记录必须是关键码有序(通常从小到大),线性表必须采用顺序存储。

代码:

/*二分法*/
int BInary_Search (int *a, int n, int key)
{
	int low, high, mid;
	low = 1; //定义最底下标为记录首位
	high = n; //定义最高下标为记录末位
	while(low<=high)
	{
		mid = (low+high)/2;
		if (key<a[mid])
			high = mid-1;
		else if (key > a[mid])
			low = mid +1;
		else 
			return mid;
	}
	return 0;
}

改进算法:
在这里插入图片描述
效果优于普通查找

斐波那契查找

利用黄金分割

下标012345678910
F0112358132134

代码:

/*斐波那契查找*/
int Fibonacci_Search (int*a,int n, int key)
{
	int low, high, mid, i, k;
	low = 1;
	high = n;
	k = 0;
	while (n>F[k]-1)
		k++;
	for (i=n;i<F[k]-1;i++) //计算n位于斐波那契数列的位置
		a[i]=a[n];
	while (low<=high)
	{
		mid = low+F[k-1]-1; //计算当前分隔的下标
		if (key<a[mid]) //若查找记录小于当前分隔符记录
		{
		high = mid-1;
		k=k-1; //斐波那契数列下标减一位
		}
		else if (key>a[mid]) //若查找记录大于当前分割记录
		{
			low = mid+1;
			k = k-2;
		}
		else 
		{
			if (mid<=n)
				return mid;
			else
				return n; //若mid>n说明是补全数值,返回n
		}
	}
	return 0}

线性索引查找

索引是把一个关键字与它对应的记录相关联的过程
分为稠密索引、分块索引和倒排索引

稠密索引

稠密索引是指在线性索引中,将数据集中的每个记录对应一个索引项。
对于稠密索引这个索引表来说,索引项一定是按照关键码有序的排列

分块索引

类似于图书馆的书架和书
分块索引:分块有序,是把数据集的记录分成了若干块,并且这些块需要满足下列两个条件:

  1. 块内无序
  2. 块间有序

倒排索引

索引项的通用结构是:

  • 次关键码
  • 记录号表
    其中记录号表存储具有相同次关键字的所有记录的记录号。这样的索引方法就是倒排索引。

二叉排序树

二叉排序树,称为二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树

  1. 若他的左子树不为空,则左子树上所有结点的值均小于它根结构的值。
  2. 若它的右子树不为空,则右子树上所有结点的值均大于它根结构的值。
  3. 它的左、右子树也分别为二叉排序树。
    代码:
/*二叉树的二叉链表结点定义*/
typedef struct BiTNode 
{
	int data;
	struct BiYNode *lchild,*rchild;
}BiTNode, *BiTree;
//递归查找二叉排序树T中是否存在key
//指针f指向T的双亲,其初值调用值为NULL
//若查找成功,则指针p指向该元素结点,并返回TRUE
//否则指针p指向查找路径上访问的最后一个结点并返回FALSE 
Status SearchBST (BiTree T, int key, BiTree f, BiTree *p)
{
	if (!T)
	{
		*p = f;
		return FALSE;
	}
	else if (key == T-> data) //查找成功
	{
		*p = T;
		return TRUE;
	}
	else if (key < T -> data)
		return SearchBST (T->lchild, key, T, p)
	else
		return SearchBST (T->rchild, key, T, p)
}

二叉排序树插入操作

代码:

//当二叉排序树T中不存在关键字等于kry的数据元素时
//插入key并返回TRUE,否则返回FALSE
Status InsertBST (BITree *T, int key)
{
	BiTree p,s;
	if (!SearchBST(*T, key, NULL, &p)) //查找不成功
	{
		s=(BiTree)malloc(sizeof(BiTNode));
		s->data= key;
		s->lchild=s->rchild=NULL;
		if(!p)
			*T=s; //插入s为新的根节点
		else if (key<p->data)
			p->lchild = s; //插入s为左孩子
		else
			p->rchild = s;
		return TRUE;
	}
	else 
		return FALSE;
		

平衡二叉树

平衡二叉树(AVL)是一种二叉排序树,其中每一个结点的左子树和右子树的高度差至多等于1

最小不平衡子树:距离插入点最近的,且平衡因子的绝对值大于1的结点为根的子树

实现原理

平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插入一个结点时,线检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡树。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值