哈希,最短路径,堆,排序,动态规划

一 最短路径

最短路径分为单源最短路径和任意两点的最短路径,前者用Dijkstra算法,后者用floyed算法。

Dijkstra算法是一种广度优先算法,以起始点层层往外扩展,直至到终点为止。其把顶点分为两个集合:

  1. 已经求出最短路径的节点集合 S

  2. 未确定最短路径的顶点集合U

通过逐渐把U中的节点不端加入到S中,直至U为空。再插入的过程中,要保证V到S中的任意顶点长度不大于V到U中任意顶点长度

假设在中间某一步的时候,上一步选取t节点作为中间节点,那么此时查看t的out vertex,那么查看V经过t到这些out vertex的边的长度的最小值是否比之前不经过t的小,如果小,则进行更新。

floyed算法:

i -> j 的最短路径无外乎两种可能:

  1. i 直接到 j

  2. i 经过若干中间节点到 j ,即Dis(i,k) + Dis(k,j)   和   Dis(i,j) 的大小比较~~

二. 哈希

Hash主要为了在O(1)时间复杂度下查找一个元素。Hash函数的定义:一般是取原始字符的某几位(或随机)映射为一个hash值,比如可以取前几位,把原始字符串分成不同的段,段之间相加得到映射后的hash值。

Hash中两个比较重要的点是:

  1. 映射后的hash值分布要均匀

  2. 映射后的hash值得冲突要尽量少

一般冲突发生后,可以解决的方法:

  1. 线性探测法:在附近依次找一个hash值为空的位置,一定能找到一个,但是增加冲突的可能,因为hash后的值会更聚集。

  2. 二次探测法:不长不是加1,步长1 2 4 8 ... 增加

  3. 伪随机

  以上三种方法属于开放定址法。还有两种方法分别是 再hash方法,链地址法。

三. 检索

  检索看的是查找成功/不成功的时候的平均查找长度ASL。不同于检索排序看中的则是元素的比较次数和元素的移动次数

  1. 顺序查找

  2. 分块查找:块间有序,块内无序,块内顺序查找。

  动态查找/静态查找。

  二叉搜索树,ASL容易受树的形态影响。因此对树的形态加个限制,变成了平衡二叉搜索树,其左右子树深度之差不超过2,只能是1,-1,0.

  AVL中比较重要的操作就是左旋,右旋操作,调整树,使得树变成平衡的树。

  旋转的情况分为下面四种情况:

    当前节点的左子树插入左节点:右旋

    当前节点的左子树插入右节点:左旋

    当前节点的右子树插入左节点:右旋

    当前节点的右子树插入右节点:左旋

四. 排序

  1. 找出数组中超过一半的数字

  维持两个数字,一个是目前出现次数比较多的数字,一个是该数字出现的次数count,遍历数组,如果当前数字和保存的数字相同,则count + 1,如果不相同,则count - 1。如果count = 0,则保存数字 = 当前的数字,重新计数,count + 1

  2. 堆建成后,如何进行堆排序呢?每次将堆顶得元素和堆的最后一次元素替换,并将最后一个原色从堆中删除,重新调整堆,依次这样可以得到一个有序的序列。堆排序不受初始数字的排列顺序影响,时间复杂度恒为O(nlogn)

  3. 插入排序:把后面未排序数组第一个数字依次插入到前面已排序数组中。时间复杂度O(nn),受初始数字序列的影响

  二分插入排序:插入排序的一种小改进,时间复杂度O(nn)

  希尔排序:根据一个递减序列 d1 d2 ... 1,d1为增量元素把原始数组划分成不同的组,对组内元素进行排序。时间复杂度O(nlogn)

  选择排序:从后面未排序数组中选择一个最大/小值插入到已排序数组中去

  冒泡排序:依次交换两个数字,使得大的在后,小的在前,每次都能把最大的一个元素沉淀到数组最后面

  快速排序:

  堆排序:

  归并排序:讲数组分成元素个数只有1/2个的小数组,依次向上进行归并。

  桶排序:将数据划分到不同的桶内,桶之间是有序的,对桶内的元素排序即可。

  基数排序:将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零. 然后, 从最低位开始, 依次进行一次稳定排序(我们常用上一篇blog介绍的计数排序算法, 因为每个位可能的取值范围是固定的从0到9).这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.

比如这样一个数列排序: 342 58 576 356, 以下描述演示了具体的排序过程(红色字体表示正在排序的数位)

第一次排序(个位):

3 4 2

5 7 6

3 5 6

0 5 8

第二次排序(十位):

3 4 2

3 5 6

0 5 8

5 7 6

第三次排序(百位):

0 5 8

3 4 2

3 5 6

5 7 6

结果: 58 342 356 576

两个问题:

  • 为什么要从低位开始向高位排序?

如果要从高位排序, 那么次高位的排序会影响高位已经排好的大小关系. 在数学中, 数位越高,数位值对数的大小的影响就越大.从低位开始排序,就是对这种影响的排序. 数位按照影响力从低到高的顺序排序, 数位影响力相同则比较数位值.

  • 为什么同一数位的排序子程序要使用稳定排序?

稳定排序的意思是指, 待排序相同元素之间的相对前后关系,在各次排序中不会改变.比如实例中具有十位数字5的两个数字58和356, 在十位排序之前356在58之前,在十位排序之后, 356依然在58之前.

稳定排序能保证,上一次的排序成果被保留,十位数的排序过程能保留个位数的排序成果,百位数的排序过程能保留十位数的排序成果.

索引查找:由索引表和数据表组成。索引表可以是线性的,也可以是树状结构的。

时间: 2024-08-27 11:27:55

哈希,最短路径,堆,排序,动态规划的相关文章

Perl 哈希、数组 排序

写在前面: 1. 注意use warnings; 后,定义变量前加my 2. 此文转载其他文章,代码修改,适合新版本perl (一) sort函数sort LISTsort BLOCK LISTsort SUBNAME LISTsort的用法有如上3种形式.它对LIST进行排序,并返回排序后的列表.假如忽略了SUBNAME或BLOCK,sort按标准字串比较顺序来进行(例如ASCII顺序).如果指定了SUBNAME,它实际上是个子函数的名字,该子函数对比2个列表元素,并返回一个小于,等于,或大于

【每日算法】图算法(遍历&MST&最短路径&拓扑排序)

图有邻接矩阵和邻接表两种存储方法,邻接矩阵很简单,这里不讨论,下面我们先看看常用的邻接表表示方法. 邻接表常用表示方法 指针表示法 指针表示法一共需要两个结构体: struct ArcNode //定义边表结点 { int adjvex: //邻接点域 ArcNode* next; }; struct VertexNode //定义顶点表结点 { int vertex; ArcNode* firstedge; }; 每个节点对应一个VertexNode,其firstedge指向边表(与当前节点邻

58. C# -- 集合(动态数组,哈希表,排序列表,堆栈,队列,点阵列)

一.先来说说数组的不足(也可以说集合与数组的区别): 1.数组是固定大小的,不能伸缩.虽然System.Array.Resize这个泛型方法可以重置数组大小,但是该方法是重新创建新设置大小的数组,用的是旧数组的元素初始化.随后以前的数组就废弃!而集合却是可变长的 2.数组要声明元素的类型,集合类的元素类型却是object. 3.数组可读可写不能声明只读数组.集合类可以提供ReadOnly方法以只读方式使用集合. 4.数组要有整数下标才能访问特定的元素,然而很多时候这样的下标并不是很有用.集合也是

Luogu P3953【NOIP2017】逛公园【最短路+拓扑排序+动态规划】

题目描述 策策同学特别喜欢逛公园.公园可以看成一张NN个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会去逛公园,他总是从1号点进去,从NN号点出来. 策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间.如果1号点 到NN号点的最短路长为dd,那么策策只会喜欢长度不超过d + Kd+K的路线. 策策

java 堆 排序学习

/** * <html> * <body> * <P> Copyright 1994 JsonInternational</p> * <p> All rights reserved. - https://github.com/Jasonandy/Java-Core-Advanced </p> * <p> Created by Jason</p> * </body> * </html> *

51nod 1241 特殊的排序(动态规划)

分析:记数组中最长的连续子串长度为maxlen(数值上连续,位置不一定连续,如2134,最长为3).首先可以证明,n-maxlen次操作可以满足条件,如最长子串最后一个为x<n,则把x+1移到最后,如果是x=n,记子串的第一个为y,把y-1移到最前,每次操作后最长连续子串长度+1,故可以满足条件.接下来证明,这是最少的移动次数.假设还有更少的,说明存在一步移动,最长连续子串长度至少+2,但移走一个元素不增加长度,把这个元素放在最前或最后最多只能增加1,矛盾. 求maxlen动态规划一下,记dp[

Problem: The World Final II(NEUOJ1175)排序+动态规划

The World Final is coming! Next week our seniors, Brother Head, Little Bin and God Tan will fight for the glory of NEU. The rule of the world final is as follow: 1. if two teams have the different solved problems, then the one who have more solved pr

Minimum Path Sum,最短路径问题,动态规划

问题描述:Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. 问题分析:参考路径问题,其实就是加权的路径问题,求最小的权值和.动态规划问题,核心递推公式,d[i][j] = min(d[i-1][j],d[i][j-1])+a[i][j]. publi

数据结构:排序算法

排序算法 <<插入排序>> *直接插入排序* 思想 每次取剩下的一个元素插入到已经有序的序列中. 代码 public static void InsertSort(int[] arr){ if(arr == null || arr.length == 0){ System.err.println("ERROR INPUT"); return; } int n = arr.length; for(int i = 1; i < n; i++){ int tem

数据结构(七)排序---排序知识点总结

回顾:排序分类 (一)插入类 直接插入排序 折半插入排序 希尔排序 本质还是插入排序 (二)交换类 冒泡排序 快速排序 (三)选择类 简单选择排序 堆排序 (四)归并类 归并排序 一:复杂度总结 (一).时间复杂度 1.平均情况下:快些排队(快希排堆) 在平均情况下,快速排序,希尔排序,归并排序,堆排序的时间复杂度都是O(nlog2n),其他都是O(n2) 2.最坏情况下 快速排序的时间复杂度为O(n2),其他的和平均情况下相同 (二).空间复杂度 快速排序是O(log2n),归并排序是O(n)