数据结构
文章平均质量分 54
spring_hui123
本人新浪博客地址 http://blog.sina.com.cn/u/5551884115
内容无特殊说明均为原创,欢迎转载分享知识,因本人尚且属于学习阶段,因此博文中可能会出现错误的知识,如有前辈发现错误请及时指出,不胜感激!
展开
-
如何使希尔排序具有稳定性
稳定上指排序前相等的数据的位置关系在排序后不发生变化直接插入排序是稳定的。希尔排序是特殊的插入排序,但因为交换值的过程中有跳跃式的交换,所以不稳定,如下图红6和蓝6在排序后发生了变化,6个数的序列,dk先取3来看所以说希尔排序是不稳定的,如何把他改进为稳定的呢,只需在原代码上加两段代码即可具体代码作用说明在图中这样每次发生交换都会有检测并且进行稳定化原创 2017-10-07 00:06:08 · 1899 阅读 · 1 评论 -
希尔排序 插入排序的升级
直接插入排序我们是知道的,它比冒泡和选择快的原因是数据交换的次数相对较少,不像冒泡那样,每次内循环遍历时两个两个数比较然后换来换去,如果是完全反序的,那就得每次都进行交换操作,交换操作可比逻辑判断操作要费时多,这也是之前问的,为什么时间复杂度明明差不多,但运行时间却天差地别,冒泡排序排10万个数据的时候居然用了1分多种。然而要减少交换操作,那就需要序列向有序化靠拢,这样实际的交换数据操作减原创 2017-10-07 18:49:51 · 236 阅读 · 0 评论 -
堆排序 选择排序的升级
选择排序的思想是每次选择未排序列中最小值的下标,使它对应的值与未排序数列中第一个的值交换内容。从而达到选择的目的。 而堆排序就是每次调整后,选出最大值在堆顶,然后使堆顶放入数列末尾,然后数列长度减1,这样就总使未排数列中的最大值放在未排数列的最后一位。然而怎么确定数列中最大的数呢,如果遍历未排数列 一个一个去比,那显然就是一般的选择排序了但我们要升原创 2017-10-07 18:50:41 · 264 阅读 · 0 评论 -
快速排序 常考排序算法
冒泡排序是交换排序,它是非常慢的,比起几种简单排序,例如选择,插入排序。冒泡排序的时间性能要差的多。因为总要交换数据,只是两个两个的比,不仅逻辑判断多,交换数据的频次也高。 但交换排序就如此失败吗。不,它反而是很成功的,因为它有个顶梁柱。那就是快速排序。 快速排序听着就很快,实际效果来说更快,如果再加入优化,那就快上天了,如果再把几种优化一融合。也许,这就是排序中的王者吧!原创 2017-10-07 18:51:42 · 323 阅读 · 0 评论 -
快速排序的优化
优化1通过时间复杂度来切入看看,最好情况为nlog2n,最坏情况为n^2。是什么导致差距如此之大呢? 最好情况就是每次分段的时候,那个分段的点都在待分段数列的中间位置,因此分布非常的平均,所有分段路线,也就是递归的层次是一样的。大家同时分到每段是1个数据的层次。 最坏情况就是顺序,每次分都是左边有,右边没有,导致右边很快就分完了,左边却一直往下分,最后就变成了0n^原创 2017-10-07 18:52:38 · 472 阅读 · 1 评论 -
快速排序的非递归实现
快速排序的思想是先从一数列中找出一个枢轴点,这个枢轴点左边的数都比它小,右边的数都比它大,也就是说枢轴点的位置已经是有序的了。例如 5 1 7 9 2 3 8 使用一次快速排序后会变成这样· · · 5 · · ·。1,2,3会在5的左边,7,8,9在5的右边,5在第四个位置,5是枢轴点,且不会再变动了。 如果最终排序完毕,数列会是 1 2 3 5 7 8 9原创 2017-10-07 18:55:31 · 1495 阅读 · 0 评论 -
归并排序
研究过归并排序和堆排序的时间复杂度的朋友们应该知道它们的时间复杂度都是nlog2n。堆排序是利用了完全二叉树,做了很多次堆调整才达到了排序的目的。相关堆排序的内容可以看看选择排序的升级---堆排序,在此不多赘述。 其实归并排序也是形似二叉树。简单来讲就是分而治之的思想。谈到 ‘分’很容易想到快速排序,快排也是分。但它是把数列从枢轴点分开。让点的边左都小 右边都大(降序则相反) ,快排分原创 2017-10-07 18:56:17 · 247 阅读 · 0 评论 -
朴素查找子串算法和KMP算法
如何在一个字符串查找子串呢?按照我们以前学过的查找方法无非是这样的。 假如就给定字符串A为“ababcabcd.....”,设要从A查找的子串a为"abc",我们就同时遍历A串,和a串,分别用i和j记录遍历的下标,如果A串的i和a串的j 各自对应的字符一样,我们就让i,j同时往后+,然而大部分情况是i和j还没到它们各自的终点就出现匹配失败了。匹配失败子串的i要置0,j退回到j这轮...原创 2018-02-09 16:35:26 · 1340 阅读 · 0 评论 -
大数据处理之Hash哈希表(一)
现在的网络公司对于数据的处理的非常看重的。比如拿百度来说,10大热搜词就是从海量的用户搜索的数据中找到的,我们想的很简单,只要把所有用户搜索的数据按搜索次数 排列下来,随便用个快排?归并?取前10种出现频次最高的不同的数据就好了,可是用户搜索的数据实在是太多了。使用快排归并那种内部排序是需要我们使用电脑内存的,现在电脑一般都是4-8G的内存。这可能连数据百分之1都存放不下。数据都不齐全,何谈排序...原创 2018-02-09 16:36:07 · 841 阅读 · 0 评论 -
大数据处理之哈希表(二)--出现频率最多的top xxx 位
上篇文章中只是求了出现频次最高的值,可是大数据处理往往需求的是top 10 ,top 100或者某一段区间的数据。显然只定义一个Hash a是不能放下的。如果是求出现频次top100呢?最起码定义 Hash arr[100]吧。比如拿计数器10000长度和数据范围为32767来说。我们最少要分4次,分别是数据取余4后 0 1 2 3的四种情况第一次余数为0,即4的倍数这一组,我们是不是要先算...原创 2018-02-09 16:37:22 · 2301 阅读 · 0 评论 -
单链表有关 环 的问题
说起关于单链表的环,无非以下几种常见问题 。 1求单链表是否有环 。 2求单链表的入环点。 3求环的长度。 对于问题1,记得我第一次接触的时候,比较暴力,直接定义了个数组存放链表所有节点的地址。 遍历链表每读到下一个节点的时候,都要和已知结点的地址数组比较,看是否相同。这种解法的优点 仅仅是的确很好想,但时间复杂度 空间复杂度都很高。 因此就要寻找更优的解法,我起初的那个很差...原创 2018-02-09 16:42:14 · 334 阅读 · 0 评论 -
直接插入排序
直接插入排序比起冒泡和选择稍微难理解一点,不过也好,毕竟是简单排序,也就是那种比一目了然多想几下的程度。 它的基本思想是什么呢? 插入插入无非就是插入,插入哪啊?插入乱序数列?那显然不可能,那是胡插。 不是插入乱序数列那就是插入有序数列嘛,非黑即白多好记的。 如何插入有序数列呢,给我的数列一般都是打乱的啊,我怎么判断哪里有序了。 其实答案就藏在身边原创 2017-10-07 18:48:28 · 351 阅读 · 0 评论 -
简单选择排序
选择排序顾名思义是选择,选择什么呢,选择的当前最小数的下标(数组)。 如果有长度为11的数组。0号位为哨兵位。从1号下标开始,1号位不管是什么数,我就先把1号位的数字1赋值给最小值下标minIndex,1号位这个位置永远是最小的(排完序后它对应的数字也应该是最小的),然后把最小值下标的数(当前下标为1)与余下的9个数依次比较,如果比较途中,有数字比1号位的数小,那么我就把那个比最小值下标要原创 2017-10-07 18:47:34 · 339 阅读 · 0 评论 -
浅谈堆排序的堆调整及时间复杂度
原创 2017-10-07 00:08:09 · 2844 阅读 · 0 评论 -
后缀表达式
后缀表达式是什么?我们平时的运算式子有符号优先级的概念,例如 3+5*(2+1),这也叫中缀表达式,我们计算时会先算括号中2+1的值 ,然后再乘以5,最后再和3相加,实际的运算过程的先后与列出式子的顺序大不相同。 人在计算前可以通过眼睛全局观察整个式子的概况然后进行计算,但是计算机却很难做到这点,在3+5*(2+1)中,计算机读到了3+,然后该读到5了,它到底是用3+5直接算出结原创 2017-10-07 00:10:57 · 486 阅读 · 0 评论 -
中缀转后缀的程序,及详细的代码说明
测试用例的结果如图源代码如下#include#include#include#include#includevoid fx(char arr[]);int main(void){char arr[]="3+5*(2-1)";char brr[]="X=A+B*(C-D)/E";char crr[]="3.14*(5.0*5.0)";原创 2017-10-07 00:12:48 · 1793 阅读 · 0 评论 -
两个关于进制转换的经典面试题
一、【30!的结果,转换成3进制有几个0】拿常见的10进制来分析例如5!中有几个0 10中有几个05!=120 一个010!=3628800 2个0在10进制中,出现0的情况无非是出现2个数相乘刚好为10,进位出现了0,5!中只有2和5能凑出10来,因此一个0;10!中有2*5 10凑出两个10来,因此2个0,和上面简单的举例结果一原创 2017-10-07 18:23:12 · 1911 阅读 · 0 评论 -
如何判断两条链表是否相交
链表如果有交点,就代表链表L1某个p1节点和链表L2某个p2节点相同。所以不管如何,最后交汇一起呈Y型或者V型。 1.那么判断是否有交点也很简单,可以定义一个数组存放各一个链表每个节点的地址,再遍历另一条链表,看是否存在节点地址和数组中的元素相同。如果相同就有交点,代码如下;Node* fx(Node *p1,Node *p2){Node * arr[20];int原创 2017-10-07 18:34:36 · 361 阅读 · 0 评论 -
八皇后及回溯算法
记着刚接触到八皇后的问题时,自己总是想不通如何使判断步骤退回来,自己套了好多个循环,最后还是这种情况 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1原创 2017-10-07 18:41:04 · 478 阅读 · 0 评论 -
冒泡排序
冒泡排序就如他的名字,每次都有泡泡浮上来,泡泡自然是最轻的,最小的,一次遍历数列侯最小的会交换到第一位(下标为1,下标0为哨兵位)。 其实也可以相反的来,每次遍历有最大的交换到最后一位,沉底法,就如石头沉到底一样。我用的就是沉底。用数组来举例,先是外层循环,设置i从1到 len-1,每次i++,从1开始因为0号下标为哨兵我们不管。至于为什么是len-1呢。因为我们知原创 2017-10-07 18:46:22 · 340 阅读 · 0 评论 -
如何获取两个单链表交点
之前的一篇博客《如何判断两条单链表是否有交点》只说了如何判断是否有交点,但并没有提及如何得到交点。 设置数组分别存储两条链表所有节点的地址,然后一 一比较?可行是可行,不过空间时间复杂度太高,不建议使用。 那有没有更高效的方法呢?方法1 从相交链表的特点来切入分析,看看下面这张图。 一般来说,相交链表会自相交点后有一段公共区域。绿色圈起部分。然而这两条红色A和蓝色B链表的长度差别是不是就是进...原创 2018-02-09 16:43:46 · 926 阅读 · 0 评论