算法:查找、排序

算法:
数据结构中的算法,指的是数据结构所具备的功能
解决特定问题的方法,它是前辈们的一些优秀的经验总结

一个算法应该具有以下五个重要的特征
有穷性:算法的有穷性是指算法必须能在执行有限个步骤之后终止;
确切性:算法的每一步骤必须有确切的定义;
输入项:一个算法有0个或多个输入;
输出项:一个算法有一个或多个输出,以反映对输入数据加工后的结果。
没有输出的算法是毫无意义的;
可行性:算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作
步骤,即每个计算步骤都可以在有限时间内完成(也称之为有效性)

如何评价一个算法:
    时间复杂度:由于计算机的性能不同,无法准确地衡量出算法执行
    所需要的时间
        因此我们用算法的执行次数来代表算法的时间复杂度
        一般使用O(公式) 一般忽略常数

常见的时间复杂度:
    // O(1)
    printf("%d",i);

    // O(logn)
    for(int i=n;i>=0;i/=2)
    {
        printf("%d",i);
    }

    // O(n)
    for(int i=0;i<n;i++)
    {
        printf("%d",i);
    }

    // O(nlogn)
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j/2)
        {
            printf("%d",i);
        }
    }

    // O(n^2)
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            printf("%d",i);
        }
    }

空间复杂度:
    执行一个程序所需要的内存空间大小,是对一个算法在运行过程中
    临时占用存储空间大小的衡量
    一般只要算法不涉及动态分配的内存以及递归,通常空间复杂度为0(1)
    类如:求第n个斐波那契数列的递归实现算法 空间复杂度0(n)

注意:对于一个算法而言,其时间复杂度与空间复杂度往往是相互影响的,
没有唯一的标准,需要结合实际综合考虑

分治:
分而治之,把一个大而复杂的问题,分解成很多小而简单的问题,利用计算机
强大的计算能力来解决问题
实现分治的方法:循环、递归

查找算法:
顺序查找
对待查找的数据没有要求,从头到尾逐一比较,在小规模的查找中较为
常见,查找效率较低
时间复杂度:0(n)
二分查找(折半查找)
待查找的数据必须有序,从数据中间位置开始比较查找,如果中间值
比key小,则从左边继续进行二分查找,反正从右边进行
时间复杂度:O(logN)
块查找(权重查找)
是一种数据处理的思想,不是一种特定的算法,当数据量非常多时,
可以先把数据进行分块处理,然后再根据分块的条件进行查找,例如
英文字典
哈希查找

查找算法:
顺序查找
对待查找的数据没有要求,从头到尾逐一比较,在小规模的查找中较为常见,查找效率较低
时间复杂度:O(N)
二分查找(折半查找)
待查找的数据必须有序,从数据中间位置开始比较查找,如果中间值比key小,则从左边继续进行二分查找,反之从右边进行。
时间复杂度:O(logN)
块查找(权重查找)
是一种数据处理的思想,不是一种特定的算法,当数据量非常多时,可以先把数据进行分块处理,然后再根据分块的条件进行查找,例如英文字典
哈希查找(Hash)
数据 经过 哈希函数 计算出数据在哈希表中的位置,然后标记位置,方便之后的查找,它的时间复杂度最高可以达到 O(1)
但是该算法有很大的局限性,不适合负数、浮点型数据、字符型数据的查找,还需要额外申请存储空间,空间复杂度高,是一种典型的以空间换时间的算法
哈希函数设计方法:
直接定址法:直接把数据当做哈希表的下标,把哈希表中该下标的位置+1
数据分析法:分析数据的特点来设计哈希函数,常用的方法是找到最大值和最小值,用 最大值-最小值+1 确定哈希表的长度,使用 数据-最小值 作为哈希表的下标访问哈希表
平方取中法、折叠法、随机数法,但都无法保证哈希数据的唯一性,出现所谓的哈希冲突,一般使用链表解决
Hash函数的应用:MD5、SHA-1都属于Hash算法中的应用

排序算法:
排序算法的稳定性:
在待排序的数据中,如果有值相同的数据,在排序的全程中都不会改变它们的先后顺序,则认为该排序算法是稳定的

冒泡:数据左右进行比较,把最大的数一直交换到最后,特点是该算法对数据的有序性敏感,在排序过程中发现有序可以立即停止排序,如果待排序的数据基本有序,则冒泡的效率非常高
    时间复杂度:最优O(N) 平均:O(N^2)
    稳定的

选择:假定最开始的位置是最小值并记录下标min,然后与后面的数据比较,如果有比min为下标的数据还要小,则更新min,最后判断如果min的值发生了改变,则交换min位置的数据与最开始位置的数据
    虽然选择排序的时间复杂度较高,但是数据交换次数少,因此实际运行速度并不慢
    是冒泡排序的变种,但是没有对数据有序性敏感,数据混乱情况下比冒泡快
    时间复杂度:O(N^2)
    不稳定的    (10 10 1)
    注意:算法的时间复杂度并不能代表算法的实际时间,有时候时间复杂度高的反而速度更快

插入:把数据看作两个部分,一部分是有序的,把剩余的数据逐个插入进去
    时间复杂度:O(N^2)
    稳定的

希尔:是插入排序的增强版,由于插入排序数据移动的速度比较慢,所有
在此基础上增加了增量的概念,从而提高排序的速度
    时间复杂度:0(N^(1.3~2))
    不稳定

快速:
    找到一个标杆p,备份标杆的值,一面从左找比val大的数据,找到后
    赋值给p,更新标杆p的位置到左标杆,然后从右边找比val小的数,
    找到后也赋值给p,同样更新p到右标杆,反复执行直到左右标杆相与
    停止,最后把val赋值回p的位置,最终回形成p左边的数都比它小,右边
    的数都比它大:然后再按照同样的方法对左右两边进行快排,最后全都有序
    快速排序的综合性能最高,因此叫做快速排列,笔试面试考最多
    时间复杂度:O(NlogN)
    不稳定

归并:
    先把一组待排序的数据拆分成单独的个体,存放到临时空间中,
    然后两两比较合并,全部合并完成后再从临时空间中拷贝给原内存
    由于需要额外的内存空间避免了数据交换的耗时,是一种典型的以空间换
    时间的算法 
    时间复杂度:O(NlogN)
    稳定 

堆:把数据当作完全二叉树看待,然后把树调整成大顶堆,然后把堆顶数据
交换到末尾,然后数量--,然后重新调整回大顶堆,重复操作,直到数量为1时
结束,既可以循环实现也可以递归实现(参考heap.c)
    时间复杂度O(NlogN)
    不稳定

计数:
    找出数据中的最大值和最小值,并创建哈希表,把数据-最小值作为
    数组的下标访问哈希表并标记数量,标记完后,遍历哈希表,当表中的值
    大于0,把下标+最小值还原数据依次放回数组中,是一种典型的以空间换时间
    的算法
    该排序算法理论上速度非常快,它不是基于比较的算法,在一定范围内整数
    排序时快于任意的一种比较排序算法,但是有很大的局限性:适合排序整型数据,
    而且数据的范围差别不宜过大,否则会非常浪费内存反而慢于比较的排序,如果
    数据越平均、重复数越多,性价比越高
    时间复杂度:O(N+k)(其中k是整数的范围)
    稳定的

桶:
    根据数据的值存储到不同的桶中,然后再调用其他的排序算法,对桶的数据
    进行排序,然后再从桶中依次拷贝回数组中,从而降低排序的规模以此提高
    排序的速度,是一种典型的以空间换时间的算法
    缺点:然后分桶、桶范围多大,这些都需要对数据有一定的了解
    时间复杂度:O(N+k)
    桶排序的稳定性取决于桶内排序使用的算法

基数:
    是桶排序的具体实现,首先创建10个队列(链式队列),然后逆序计算
    出数据的个、十、百...位数,然后入到对应的队列中,结束后依次从队列中
    出队回数组中,数据下一位继续入队,依次循环,最大值的位数就是循环次数
    缺点:只适合排序正整数数据,又要准备队列
    时间复杂度:O(N+k)
    稳定的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值