数据结构和算法--查找算法

数据结构和算法

1. 顺序查找

前提:顺序查找适合于存储结构为顺序存储或链接存储的线性表
时间复杂度:时间复杂度为O(n)。
基本思路:没啥说的,按顺序一个一个查找,暴力但低效;

2. 二分查找

前提:顺序查找适合于存储结构为顺序存储或链接存储的线性表
时间复杂度:时间复杂度为O(log2n)
基本思想:也称为是折半查找,属于有序查找算法。
用给定值value先与中间结点的关键字比较,中间结点把线性表分成两个子表,若相等则查找成功;若不相等,再根据value与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
代码实现:

int FindValue(int a[], int begin, int end, int value)
{
	// 异常情况判断
	if(begin >= end)
		return -1;
		
	int mid = begin + (end - begin)/2;
	if(value == a[mid])
		return mid;
	if(value < a[mid])
		return FindValue(a, begin, mid - 1,value);
	if(value > a[mid])
		return FindValue(a,mid +1; end,value);
}

3. 差值查找

前提:顺序查找适合于存储结构为顺序存储或链接存储的线性表
时间复杂度:查找成功或者失败的时间复杂度均为O(log2(log2n))。
基本思想:基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。
折半查找这种查找方式,不是自适应的(也就是说是傻瓜式的)。二分查找中查找点计算如下:
  mid=(begin + end)/2, 即mid=low+1/2*(end-begin);
通过类比,我们可以将查找的点改进为如下:
  mid = begin + (value - a[begin])/(a[end] - a[begin]) * (end - begin);
  也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字value,这样也就间接地减少了比较次数。
  注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。
代码实现

int FindValue(int a[], int begin, int end, int value)
{
	// 异常情况判断
	if(begin >= end)
		return -1;
	
	// 查找点根据数值的比例,动态调整	
	int mid = begin + (value - a[begin])/(a[end] - a[begin]) * (end - begin);
	if(value == a[mid])
		return mid;
	if(value < a[mid])
		return FindValue(a, begin, mid - 1,value);
	if(value > a[mid])
		return FindValue(a,mid +1; end,value);
}

4. 斐波那契查找

**前提:**元素必须是有序的,如果是无序的则要先进行排序操作。
基本思想:也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。
**时间复杂度:**时间复杂度为O(log2n)
斐波那契查找
参考:https://www.cnblogs.com/bethunebtj/p/4839576.html

5. 树表查找

二叉查找树
也称二叉搜索树,或二叉排序树。其定义也比较简单,要么是一颗空树,要么就是具有如下性质的二叉树:

  1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点;
  5. 二叉查找树进行中序遍历,即可得到有序的数列。

平衡二叉树
又称AVL树,它是一种特殊的二叉排序树。AVL树或者是一棵空树,或者是具有以下性质的二叉树:

  1. 左子树和右子树都是平衡二叉树;
  2. 左子树和右子树的深度(高度)之差的绝对值不超过1;
  3. 键值不重复;
class AVLNode
{
public:
    int key;            //结点的值
    int height;         //结点的高度,根结点为0
    int value;			// value
    AVLNode* left;      //左孩子
    AVLNode* right;     //右孩子

    /*构造函数*/
    AVLNode(int k, AVLNode* left, AVLNode* right) :key(k), height(0), left(left), right(right) {}
};

https://www.cnblogs.com/sench/p/7786718.html

6. 分块查找

7. 哈希查找

发布了59 篇原创文章 · 获赞 22 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Martin_chen2/article/details/90726757