数据结构和算法
- 查找算法
- 子字符串查找
- 相同字符串查找
- 排序算法:
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. 树表查找
二叉查找树:
也称二叉搜索树,或二叉排序树。其定义也比较简单,要么是一颗空树,要么就是具有如下性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点;
- 二叉查找树进行中序遍历,即可得到有序的数列。
平衡二叉树:
又称AVL树,它是一种特殊的二叉排序树。AVL树或者是一棵空树,或者是具有以下性质的二叉树:
- 左子树和右子树都是平衡二叉树;
- 左子树和右子树的深度(高度)之差的绝对值不超过1;
- 键值不重复;
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