数据结构和算法学习五,之查找

http://blog.csdn.net/feixiaoxing/article/details/6844723

无论是数据库,还是普通的ERP系统,查找功能数据处理的一个基本功能。数据查找并不复杂,但是如何实现数据又快又好地查找呢?前人在实践中积累的一些方法,值得我们好好学些一下。我们假定查找的数据唯一存在,数组中没有重复的数据存在。

(1) 普通的数据查找

设想有一个1M的数据,我们如何在里面找到我们想要的那个数据。此时数据本身没有特征,所以我们需要的那个数据可能出现在数组的各个位置,可能在数据的开头位置,也可能在数据的结束位置。这种性质要求我们必须对数据进行遍历之后才能获取到对应的数据。

int find(int array[], int  length, int value)
{
    if(NULL == array || 0 == length)
        return -1;

    for(int index = 0; index < length; index++){
        if(value == array[index])
            return index;
        }
    return -1;
}

分析:

由于我们不清楚这个数据判断究竟需要多少次。但是,我们知道,这样一个数据查找最少需要1次,那么最多需要n次,平均下来可以看成是(1+n)/2,差不多是n的一半。我们把这种比较次数和n成正比的算法复杂度记为o(n)。

(2)上面的数据没有任何特征,这导致我们的数据排列地杂乱无章。试想一下,如果数据排列地非常整齐,那结果会是什么样的呢?就像在生活中,如果平时不注意收拾整齐,那么找东西的时候非常麻烦,效率很低;但是一旦东西放的位置固定下来,所有东西都归类放好,那么结果就不一样了,我们就会形成思维定势,这样查找东西的效率就会非常高。那么,对一个有序的数组,我们应该怎么查找呢?二分法就是最好的方法。

int binary_sort(int array[], int length, int value)
{
    if(NULL == array || 0 == length)
        return -1;

    int start = 0;
    int end = length -1;

    while(start <= end){

        int middle = start + ((end - start) >> 1);
        if(value == array[middle])
            return middle;
        else if(value > array[middle]){
            start = middle + 1;
        }else{
            end = middle -1;
        }
    }

    return -1;
}

分析:

上面我们说到普通的数据查找算法复杂度是o(n)。那么我们可以用上面一样的方法判断一下算法复杂度。这种方法最少是1次,那么最多需要多少次呢?我们发现最多需要log(n+1)/log(2)即可。大家可以找个例子自己算一下,比如说7个数据,我们发现最多3次;如果是15个数据呢,那么最多4次;以此类推,详细的论证方法可以在《算法导论》、《计算机编程艺术》中找到。明显,这种数据查找的效率要比前面的查找方法高很多。

(3) 上面的查找是建立在连续内存基础之上的,那么如果是指针类型的数据呢?怎么办呢?那么就需要引入排序二叉树了。

排序二叉树的定义很简单:

(1)非叶子节点至少一边的分支非NULL;

(2)叶子节点左右分支都为NULL;

(3)每一个节点记录一个数据,同时左分支的数据都小于右分支的数据。

可以看看下面的定义:

typedef struct _NODE
{
    int data;
    struct _NODE* left;
    struct _NODE* right;
}NODE;

那么查找呢,那就更简单了。

const NODE* find_data(const NODE* pNode, int data){
    if(NULL == pNode)
        return NULL;

    if(data == pNode->data)
        return pNode;
    else if(data < pNode->data)
        return find_data(pNode->left, data);
    else
        return find_data(pNode->right, data);
}

(4)同样,我们看到(2)、(3)都是建立在完全排序的基础之上,那么有没有建立在折中基础之上的查找呢?有,那就是哈希表。

哈希表的定义如下:

1)每个数据按照某种聚类运算归到某一大类,然后所有数据链成一个链表;

2)所有链表的头指针形成一个指针数组。

这种方法因为不需要完整排序,所以在处理中等规模数据的时候很有效。其中节点的定义如下:

typedef struct _LINK_NODE
{
    int data;
    struct _LINK_NODE* next;
}LINK_NODE;

那么hash表下面的数据怎么查找呢?

LINK_NODE* hash_find(LINK_NODE* array[], int mod, int data)
{
    int index = data % mod;
    if(NULL == array[index])
        return NULL;

    LINK_NODE* pLinkNode = array[index];
    while(pLinkNode){
        if(data == pLinkNode->data)
            return pLinkNode;
        pLinkNode = pLinkNode->next;
    }

    return pLinkNode;
}

分析:

hash表因为不需要排序,只进行简单的归类,在数据查找的时候特别方便。查找时间的大小取决于mod的大小。mod越小,那么hash查找就越接近于普通查找;那么hash越大呢,那么hash一次查找成功的概率就大大增加。

时间: 2024-10-13 17:26:22

数据结构和算法学习五,之查找的相关文章

数据结构与算法JavaScript (五) 串(经典KMP算法)

数据结构与算法JavaScript (五) 串(经典KMP算法) KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右. 通过上一章显而易见BF算法也是属于前缀的算法,不过就非常霸蛮的逐个匹配的效率自然不用提了O(mn),网上蛋疼的KMP是讲解很多,基本都是走的高大上路线看的你也是一头雾水,我试

数据结构与算法学习之路:背包问题的贪心算法和动态规划算法

一.背包问题描述: 有N种物品和一个重量为M的背包,第i种物品的重量是w[i],价值是p[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包重量,且价值总和最大. 二.解决方法: 1.贪心算法:贪心算法基于的思想是每一次选择都作当前最好的选择,这样最后的结果虽然不一定是最优解,但是也不会比最优解差很多. 举个例子说明可能好懂一些:一帮基友去聚餐,菜是一份一份上的,我每一次夹菜都只夹牛肉/海鲜吃,可能到最后我吃的牛肉/海鲜很多,但不一定代表我吃掉的东西的总价值最高,但是相对来说价值也很高

数据结构与算法实践 之 二分查找初识

今天起,我要对数据结构和基本的算法进行一些简单的复习,并在复习的基础上对其进行深入的挖掘.这篇文章先对二分查找进行一个简要的复习,在之后的文章中会对其进行深入的学习. 二分查找又叫折半查找,是最基本的几种查找算法之一.简单的看,二分法查找主要应用于在一个有序数列中进行元素的查找,其基本思路是,先用我们要查找的元素与这个有序数列中的中间位置的元素进行比较(在此我们姑且称这个元素为"中间位置元素"吧,至于这个元素怎么求我在后面会详细说明),如果相等,则返回这个"中间位置元素&qu

数据结构和算法学习

Algorithms, 4th Edition 不过一遍都不好意思说你学过算法           学习资料: 怎样学算法? 如何学习数据结构?

数据结构与算法——学习整理记录

===注:此文由本人结合网上资源整理总结而来,仅代表个人的学习与理解,如有错漏,欢迎指正!=== # 1. 数据结构 ## 1.1 数据结构是什么? 数据结构,直白地理解,就是研究数据的逻辑关系与存储方式的一门学科. 可以简单的分为:数据的逻辑结构(逻辑关系)和数据的存储结构(物理结构). 它是以某种形式将数据组织在一起的集合,它不仅存储数据,还支持访问和处理数据的操作. ### 1.1.1 数据的逻辑结构 数据的逻辑结构,简单地理解,就是指的数据之间的逻辑关系. 数据之间的逻辑关系可简单的分为

数据结构和算法学习总结01 绪论

数据结构实际上是数据元素之间的关系的集合 数据结构分为    1.逻辑结构      2.物理结构(逻辑结构的数据元素的存储方式)                            逻辑结构分为  1.集合结构   数据元素无关系,只是属于一个集合                            2.线性结构   数据元素间1对1的关系                            3.树形结构   数据元素间1对多的关系                            

数据结构及算法学习(一)

一.数据结构范畴 数据结构是一门与程序设计密切相关的课程,而程序设计就是算法+数据结构,算法即是处理数据的策略,而数据结构就是表达程序设计的模型,可以说任何一个程序设计问题,我们都可以从算法和模型出发.概而言之,数据结构就是描述了程序设计的数学模型及在其程序设计上的表示和实现. 二.基本概念 (1)数据:是计算机处理信息的载体,是其某种特定的符合表达形式的集合,它的定义范畴会随着计算机的发展而不断扩大,最初的数据范畴是数字,而现在发展到图片.音频.视频等多种形式.而其的每个个体叫数据元素.而每个

数据结构与算法学习之(介绍)

数据结构与算法介绍 数据结构与算法的重要性 算法是程序的灵魂,优秀的程序可以在海量数据计算时,任然保持高速运算 框架和缓存技术的核心时算法 高薪 数据结构与算法的关系 数据(data)结构(Structure)是一门研究组织数据方式的学科,有了编程语言也就有了数据结构 程序 = 数据结构 + 算法 数据结构是算法的基础 数据结构包括线性结构与非线性结构 线性结构 线性结构是最常用的数据结构,特点是元素之间存在一对一的线性关系 线性结构有两种不同的存储结构,即顺序存储结构和链式存储结构 线性结构常

数据结构与算法学习(介绍)

数据结构与算法介绍 数据结构与算法的重要性 算法是程序的灵魂,优秀的程序可以在海量数据计算时,任然保持高速运算 框架和缓存技术的核心时算法 高薪 数据结构与算法的关系 数据(data)结构(Structure)是一门研究组织数据方式的学科,有了编程语言也就有了数据结构 程序 = 数据结构 + 算法 数据结构是算法的基础 数据结构包括线性结构与非线性结构 线性结构 线性结构是最常用的数据结构,特点是元素之间存在一对一的线性关系 线性结构有两种不同的存储结构,即顺序存储结构和链式存储结构 线性结构常