数据结构与算法
老周聊架构
微信公众号:老周聊架构
展开
-
数据结构与算法分析:(十六) 平衡二叉树
一、前言前面我们讲了二叉树以及二叉查找树,没有看的可以点击下面的链接看一下:数据结构与算法分析:(十四) 二叉树数据结构与算法分析:(十五) 二叉查找树看完前两篇,今天的平衡二叉树就如鱼得水一般了。下面我们就进入正题了。平衡二叉树也叫AVL(Adelson Velskii 和 Landis 三人的缩写),AVL树的出现就是为了解决前面二叉查找树退化成链表导致时间复杂度为 O(n)。AVL树是高度平衡的而二叉树,必须保证树的深度是 O(logn\log nlogn)。它的特点是:AVL树中任何节点原创 2020-05-13 21:43:51 · 639 阅读 · 4 评论 -
数据结构与算法分析:(十五) 二叉查找树
上一篇我们学了树、二叉树以及二叉树的遍历。请戳:数据结构与算法分析:(十四) 二叉树二叉树的种类各种各样,这一篇我们主要来讲二叉查找树。二叉查找树最大的特点就是,支持动态数据集合的快速插入、删除、查找操作。一、二叉查找树(Binary Search Tree)二叉树的一个重要应用是它们在查找中的使用,它不仅仅支持快速查找一个数据,还支持快速插入、删除一个数据。这里提一个小问题:我们之前讲过散...原创 2020-04-16 00:51:16 · 570 阅读 · 0 评论 -
数据结构与算法分析:(十四) 二叉树
一、前言前面我们讲了都是线性表结构,比如:数组、链表、栈、队列等。今天我们终于可以讲一讲树了,树是非线性结构。我们都知道,对于大量的输入数据,链表的线性访问太慢,不宜使用。我们今天讲的树,其大部分操作的运行时间平均为 O(logn\log nlogn)。讲二叉树之前我们先来思考一下这几个问题。二叉树有哪几种存储方式?什么样的二叉树适合用数组来存储?带着问题与思考,看完以后顿时会对二叉树的设...原创 2020-04-14 00:07:57 · 748 阅读 · 0 评论 -
数据结构与算法分析:(十三)哈希算法
前面我们花了两篇把散列表搞清楚了。详情请戳:数据结构与算法分析:(十一)散列表(上)数据结构与算法分析:(十二)散列表(下)可见散列表的重要性!那讲哈希算法为啥把前两篇的散列表的文章贴出了呢?难道它们有什么关系?没错,有关系,而且关系还很大。我们经常听到有人把散列表叫作哈希表或者Hash 表,把哈希算法叫作Hash 算法或者散列算法。那到底什么是哈希算法呢? 我们接下来就来进入正题。一、什...原创 2020-04-04 21:43:56 · 936 阅读 · 0 评论 -
数据结构与算法分析:(十二)散列表(下)
上一篇我们讲了散列表的概念、散列函数和散列冲突:数据结构与算法分析:(十一)散列表(上)这一篇我们来讲一下如何设计散列函数以及深入探讨散列函数与散列冲突这两个问题。一、如何设计散列函数?散列函数设计的好坏,决定了散列表冲突的概率大小,也直接决定了散列表的性能。那什么才是好的散列函数呢?首先,散列函数的设计不能太复杂。过于复杂的散列函数,势必会消耗很多计算时间,也就间接的影响到散列表的性能。...原创 2020-04-03 23:58:35 · 562 阅读 · 0 评论 -
数据结构与算法分析:(十一)散列表(上)
文章目录一、散列表概念二、散列函数三、散列冲突一、散列表概念散列表(Hash Table),我们平时叫它哈希(Hash)表。散列表的实现常常叫做散列(hashing)。散列是一种用于以常数平均时间执行插入、删除和查找的技术。但是,那些需要元素间任何排序信息的树操作将不会得到有效的支持。散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。可以说,如...原创 2020-03-29 21:47:44 · 690 阅读 · 0 评论 -
数据结构与算法分析:(十)跳表
一、前言上一篇我们讲了关于数组的二分查找算法,数据结构与算法分析:(九)二分查找算法。二分查找的底层依赖的是数组随机访问的特性,所以只能用数组来实现。如果数据存储在链表中,就真的没法用二分查找算法了吗?答案是有办法的,我们只需要对链表稍加改造,就可以支持二分查找算法,改造后的数据结构我们称之为跳表(Skip List)。我们先说下跳表这个数据结构的优缺点后再来分析详细过程。对于一个需要频繁...原创 2020-03-21 21:07:44 · 1362 阅读 · 0 评论 -
数据结构与算法分析:(九)二分查找算法
一、前言二分查找算法是针对有序数据集合的查找算法,将原本时间复杂度是线性时间提升到了对数时间范围,大大缩短了搜索时间。二分查找算法的思想非常简单,但细节是魔鬼。也就是你想写成没有bug的二分查找算法很难,出错原因主要集中在判定条件和边界值的选择上,很容易就会导致越界或者死循环的情况。1、思想二分查找又称折半查找,它是一种效率较高的查找方法。折半查找的算法思想是将数列按有序化(递增或递减)排列...原创 2020-03-20 01:05:25 · 2073 阅读 · 2 评论 -
数据结构与算法分析:(八)如何写好递归代码?
一、前言相信大家在真实项目中,很少用递归,宁愿把这个递归代码改写成迭代循环的非递归写法。笼统的讲,所有的递归代码都可以改写为迭代循环的非递归写法。如何做?抽象出递推公式、初始值和边界条件,然后用迭代循环实现。为啥我们宁愿改成迭代循环的非递归写法呢?因为在实际项目中用递归,一不小心就容易搞成堆栈溢出抛异常。我们这么怕写递归代码是因为我们可能还没有掌握透递归的精髓。其实也没有那么可怕,不信和我一起开...原创 2020-03-07 21:17:59 · 695 阅读 · 0 评论 -
数据结构与算法分析:(七)队列
一、队列的定义队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。我们知道,栈只支持两个基本操作:入栈 push()和出栈 pop()。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队 enqueue()...原创 2020-03-04 23:20:10 · 899 阅读 · 0 评论 -
数据结构与算法分析:(六)栈
一、栈的定义栈是限定仅在表尾进行插入和删除操作的线性表。允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。栈的插入操作,叫做进栈,也称压栈、入栈。 栈的删除操作,叫做出栈,也有的叫做弹栈。了解完栈的定义后,小伙伴们似乎发现了栈相对于数组和链表来说好像有点鸡...原创 2020-03-01 23:09:43 · 2046 阅读 · 0 评论 -
数据结构与算法分析:(五)循环链表
一、前言相信小伙伴们在前面两篇文章的详细介绍已经对单向链表、双向链表有一个很清晰的认识了。数据结构与算法分析:(三)单向链表数据结构与算法分析:(四)双向链表接下来我们来介绍循环链表,你把单向链表、双向链表搞清楚了的话,循环链表自然也不难了。循环链表可分为:单向循环链表、双向循环链表。1、单向循环链表:单向循环链表跟单向链表唯一的区别就在尾结点。我们知道,单向链表的尾结点指针指向空...原创 2020-02-28 20:24:23 · 538 阅读 · 0 评论 -
数据结构与算法分析:(四)双向链表
一、双向链表介绍我们上一篇主要介绍了关于单向链表的操作,数据结构与算法分析:(三)单向链表。我们先来介绍下单向链表与双向链表的一些差异:1、单向链表只能从头遍历到尾或者从尾遍历到头(一般从头到尾)。链表相连的过程是单向的,实现的原理是上一个链表中有一个指向下一个链表的引用。缺点:a、单向链表不能自我删除,需要先找到被删除节点的前一个节点front,使用front节点来辅助删除,不方...原创 2020-02-25 00:30:39 · 1562 阅读 · 0 评论 -
数据结构与算法分析:(三)单向链表
一、什么是链表?链表是一种物理上非连续、非顺序的存储结构,数据元素之间的顺序是通过每个元素的指针(类似C语言中的指针,Java中是引用)关联的。链表由一系列节点组成,每个节点一般至少会包含两部分信息:一部分是元素数据本身,另一部分是指向下一个元素地址的“指针”。这样的存储结构让链表相比其他线性的数据结构来说,操作会复杂一些。说到链表,我们经常拿来与数组比。我们先看下面一张图再来对比它们的各自...原创 2020-02-22 19:04:10 · 864 阅读 · 5 评论 -
数据结构与算法分析:(二)数组
一、前言这一篇我们来讲一下数组这种数据结构,相信大家在项目中也经常用到数组,数组是一种最基础的数据结构。虽然数组简单,但是设计者最初的想法你是否真正的了解呢?那么问题来了,什么是数组?我们先给出定义:数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。讲数组之前,我们先来回顾下线性表与非线性表。1、线性表顾名思义,线性表就是数据排成像一条线一样的...原创 2020-02-18 19:10:37 · 451 阅读 · 0 评论 -
数据结构与算法分析:(一)复杂度分析
文章目录一、前言二、什么是复杂度分析?三、为什么要进行复杂度分析?四、如何进行复杂度分析?五、空间复杂度分析六、常用的复杂度级别七、最好、最坏、平均、均摊时间复杂度一、前言评判代码的性能好坏,有一个很重要的指标——复杂度。复杂度包括时间复杂度和空间复杂度,相信大家在各种书上都有见到过,但用起来又差点感觉,说实话,就是没吃透这个知识。这个专栏我们就来吃透它。我们都知道,数据结构和算法本身解决的是...原创 2020-02-07 00:10:42 · 1086 阅读 · 0 评论 -
【十大排序算法】(十一)总结
1、十大排序算法的思维导图2、十大排序算法的复杂度3、十大排序算法总结【十大排序算法】(一)冒泡排序算法【十大排序算法】(一)冒泡排序算法(优化)【十大排序算法】(三)选择排序算法【十大排序算法】(四)堆排序算法【十大排序算法】(五)插入排序算法【十大排序算法】(六)希尔排序算法【十大排序算法】(七)归并排序算法【十大排序算法】(八)计数排序算法【十大排序算法】(九)桶排序...原创 2019-11-22 17:51:36 · 316 阅读 · 0 评论 -
【十大排序算法】(十)基数排序算法
一、基本思想相比其它排序,主要是利用比较和交换,而基数排序则是利用分配和收集两种基本操作。基数排序是一种按记录关键字的各位值逐步进行排序的方法。此种排序一般适用于记录的关键字为整数类型的情况。所有对于字符串和文字排序不适合。实现:将所有待比较数值(自然数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个...原创 2019-11-22 17:36:00 · 727 阅读 · 0 评论 -
【十大排序算法】(九)桶排序算法
一、基本思想桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket Sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。二、算法分析1、算法描述设置一个定量的数组当作空桶;遍历输入数据,并且把数据一个一个放到对应的桶里去;对...原创 2019-11-22 01:19:41 · 1345 阅读 · 0 评论 -
【十大排序算法】(八)计数排序算法
一、基本思想计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。二、算法分析1、算法描述找出待排序的数组中最大和最小的元素;统计数组中每个值为i的元素出现的次数,存入数组C的第i项;对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);反向填充目标数组:将...原创 2019-11-21 22:32:03 · 463 阅读 · 2 评论 -
【十大排序算法】(七)归并排序算法
一、基本思想归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。二、算法分析1、算法描述把长度为n的输入序列分成两个长度为n/2的子序列;对这两个子序列分别采用归并排序;将两个排...原创 2019-11-21 12:58:16 · 1571 阅读 · 0 评论 -
【十大排序算法】(六)希尔排序算法
一、基本思想希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。二、算法分析先取一个正整数 d...原创 2019-11-20 23:02:16 · 559 阅读 · 5 评论 -
【十大排序算法】(五)插入排序算法
一、基本思想选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。二、算法分析1、算法描述n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:初始状态:无序区为...原创 2019-11-20 00:12:17 · 877 阅读 · 0 评论 -
【十大排序算法】(四)堆排序算法
一、基本思想先开始堆排序算法之前我们先来了解下什么是堆?堆分为两种:大顶堆和小顶堆,两者的差别主要在于排序方式。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:大顶堆的存储结构为:{19,16,15,9,8,1}小顶堆的存储结构为:{1,8,9,15,16,19}我举的是两个有序...原创 2019-11-18 19:36:53 · 658 阅读 · 3 评论 -
【十大排序算法】(三)选择排序算法
一、基本思想选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。二、算法分析1、算法描述n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:初始状态:无序区为...原创 2019-11-18 00:28:10 · 1375 阅读 · 0 评论 -
【十大排序算法】(二)快速排序算法
一、基本思想通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。二、算法分析1、算法描述快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:从数列中挑出一个元素,称为 “基准”(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比...原创 2019-11-17 15:00:52 · 2346 阅读 · 2 评论 -
【十大排序算法】(一)冒泡排序算法(优化)
一、优化第一版优化第一版是针对类似 int[] arr = {3,2,1,4,5,6,7,8,9; 这样的有很多已经排好序的数组,为了不让它做无用的循环,对于此场景进行的优化,优化代码如下:// 优化第一版public static void bubbleSort2(int[] arr, int len) { for (int i = 0; i < len; i++) { ...原创 2019-11-16 21:30:24 · 1942 阅读 · 7 评论 -
【十大排序算法】(一)冒泡排序算法
一、基本思想在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。二、算法分析首先我们给定一个数组 int[] arr = {1,28,3,21,11,7,6,18};下面我们来直观的描述下冒泡排序算法的过程:1、检查是否 1 > 28;...原创 2019-11-16 17:11:12 · 8585 阅读 · 2 评论 -
【算法】将字符串B插入字符串A使产生的字符串是一个回文串,并统计回文个数
1、题目:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。现在她非常好奇有没有办法将字符串B插入字符串A使产生的字符串是一个回文串。你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法。例如:A = “...原创 2019-09-29 13:37:52 · 1403 阅读 · 0 评论 -
【数据结构】之二叉堆
一、二叉堆是什么?二叉堆 本质上就是一颗 二叉树 ,而且是完全二叉树。而根据根节点数据的不同又分为:最大堆 和 最小堆。完全二叉树:每一层都是二叉树,都被填满 ,除了最低/最下面的一层,并且所有的最底层顶点都尽力向左靠拢。什么是最大堆?父节点的值 永远 大于等于 两个 孩子节点 的值。什么是最小堆?父节点的值 永远 小于等于 两个 孩子节点 的值。二、二叉堆的特性自我调整:当插入...原创 2019-09-04 00:44:11 · 441 阅读 · 0 评论 -
java实现整数分解几个质数的积并统计3出现的次数
上一篇文章已经实现了一个整数分解为两个质数乘积,但针对这张图片,还有一个附加题,统计3出现的次数。下面我们来看下思路:最优思路:从数字规律着手,提高时间效率如果第i位(从低位向高位开始)上的数字是0,那么第i位可能出现1的次数仅由更高位决定(如果没有高位,则视高位为0),等于更高位数字*当前位数的权重10^(i-1);如果第i位上的数字为1,则第i位上可能出现1的次数不仅受更高位影响还受...原创 2019-04-12 20:52:03 · 538 阅读 · 0 评论 -
java实现一个整数分解为两个质数乘积
看到朋友在群里发的这个图片,笔算了半天索性用代码实现!!!如图哈哈哈哈哈哈哈哈哈代码如下:package com.test;/** * @author riemann * @date 2019/04/11 23:55 */public class TestPrimeNumber { public static void main(String[] args) { ...原创 2019-04-12 01:35:31 · 4766 阅读 · 3 评论 -
用java自己实现一个LRU
LRU 原理LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。实现一最常见的实现是使用一个链表保存缓存数据,详细算法实现如下:新数据插入到链表头部;每当缓存命中(即缓存数据被访问),则将数据移到链表头部;当链表满的时候,将链表尾部的数据丢弃。分析【命中率】...原创 2019-03-22 00:06:29 · 2125 阅读 · 0 评论