zoukankan      html  css  js  c++  java
  • 重学数据结构系列之——静态查找表查找算法

    学习来源:计蒜客

    1.认识查找

    就是在一个集合里面找到某个元素。集合就叫查找表

    通常对查找表有 4 种操作:

    查找:在查找表中查看某个特定的记录是否存在
    检索:查找某个特定记录的各种属性
    插入:将某个不存在的数据元素插入到查找表中

    删除:从查找表中删除某个特定元素


    如果对查找表只执行前两种操作,则称这类查找表为 静态查找表(static search table)。静态查找表建立以后,就不能再执行插入或删除操作,查找表也不再发生变化。对应的,如果对查找表还要执行后两种操作,则称这类查找表为动态查找表(dynamic search table)


    下面的查找算法都是针对静态查找表的,比如顺序查找、折半查找、分块查找等;而对于动态查找表,往往使用二叉平衡树、B-树或哈希表来处理。


    2.查找算法的好坏

    用平均查找长度来比较(我们当做查找表中的每个元素被查找的概率都是相等的),平均查找长度的计算:将查找每个元素时的比较次数加起来,再除以元素总个数n


    3.顺序查找算法

    就是跟查找表的每个元素逐一比较,找到就返回索引,找不到返回-1

    简单的查找代码:(分为有序表的查找和无序表的查找)下面是有序表的查找,无序的查找把下面的search函数的else if 语句删除即可

    时间复杂度O(n)
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    class Vector {
    private:
        int size, length;
        int *data;
    public:
        Vector(int input_size) {
            size = input_size;
            length = 0;
            data = new int[size];
        }
        ~Vector() {
            delete[] data;
        }
        bool insert(int loc, int value) {
    		//插入位置的范围判断
            if (loc < 0 || loc > length) {
                return false;
            }
            if (length >= size) {
    			//若当前线性表的长度大于等于容量时,就扩容
                expand();
            }
    		//将loc后面的数据全部后移,从最后一个元素开始移
            for (int i = length; i > loc; --i) {
                data[i] = data[i - 1];
            }
    		//插入该位置,并长度+1
            data[loc] = value;
            length++;
            return true;
        }
        void expand() {
            int * old_data = data;
            size = size * 2;
            data = new int[size];
            for (int i = 0; i < length; ++i) {
                data[i] = old_data[i];
            }
            delete[] old_data;
        }
        int search(int value) {
    		for (int i = 0; i < length; i++) {
    			if (data[i] == value) {
    				return i;
    			}else if (data[i] > value) {
    				return -1;
    			}
    		}
    		return -1;
        }
        bool remove(int index) {
            if (index < 0 || index >= length) {
                return false;
            }
            for (int i = index + 1; i < length; ++i) {
                data[i - 1] = data[i];
            }
            length = length - 1;
            return true;
        }
        void print() {
            for (int i = 0; i < length; ++i) {
                if (i > 0) {
                    cout << " ";
                }
                cout << data[i];
            }
            cout << endl;
        }
    };
    int main() {
        Vector a(100);
        a.insert(0, 2);
        a.insert(1, 4);
        a.insert(2, 6);
        a.insert(3, 8);
        a.insert(4, 10);
    
        cout << a.search(4) << endl;
        cout << a.search(5) << endl;
        return 0;
    }

    结果:



    4.有序表查找的优化——折半查找

    由于相当于向二叉树那样分叉,时间复杂度就是O(logn)

    把上面的search函数改了即可
    int search(int value) {
    		//初始化二分查找的左右范围
    		int left = 0, right = length -1;
    		//左边必须小于等于右边
    		while (left <= right) {
    			int mid = (left + right) / 2;
    			if (data[mid] == value) {
    				return mid;
    			}
    			//暂时找不到就相应更新左或右的范围
    			else if (data[mid] < value) {
    				left = mid + 1;
    			}else{
    				right = mid -1;
    			}
    		}
    		//来到这说明left > right,查找不成功
    		return -1;
        }



  • 相关阅读:
    实验九——基本数据类型存储及应用总结
    实验八——函数定义及调用总结
    实验7--函数定义及调用总结
    实验五——循环结构学习总结
    实验四—多分支结构及本章总结
    第二次作业及总结——数据类型和运算符
    160809132 梁佳佳
    实验12——指针的基础应用2
    实验11——指针的基础应用
    实验十——一维数组的定义及引用
  • 原文地址:https://www.cnblogs.com/cnsec/p/13286539.html
Copyright © 2011-2022 走看看