
数据结构与算法
文章平均质量分 51
ashane1314
不忘初心
展开
-
堆和栈
堆(Heap)与栈(Stack)是开发人员必须面对的两个概念,在理解这两个概念时,需要放到具体的场景下,因为不同场景下,堆与栈代表不同的含义。一般情况下,有两层含义:(1)程序内存布局场景下,堆与栈表示两种内存管理方式;(2)数据结构场景下,堆与栈表示两种常用的数据结构。1.程序内存分区中的堆与栈1.1 栈简介栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。参考如下代码:int main() { int b; //栈 char s原创 2020-10-27 21:42:40 · 2920 阅读 · 0 评论 -
判断二叉树是否镜像对称,编程实现
思想:若此树就一个节点或者没有节点,则为对称。 若此树不值一个节点,则分别比较其左节点和右节点的值。 然后在比较左节点和右节点的比较中,在分别比较,左节点的左子树跟右节点的右子树,左节点的右子树,跟右节点的左子树是否对称相等。 同时注意,左节点为空和左节点不为空右节点不为空场景。type Tree struct { Data interface{} Left *Tree Right *Tree}/*判断二叉树是否镜像对称,编程实现*/func MirrorTree(tree T原创 2020-06-28 04:30:57 · 438 阅读 · 0 评论 -
实现一个最大栈,包含Push、Pop、Max方法,Max方法要求返回当前栈内最大元素值
简单版package mainimport "fmt"type Stack struct { Value []int MaxV int MinV int}func (this *Stack) Push(i int) { this.Value = append(this.Value, i) if i > this.MaxV { this.MaxV = i } if this.MinV == 0 || i < this.MinV { this.MinV原创 2020-06-28 03:52:28 · 748 阅读 · 0 评论 -
redis底层数据结构
原创 2019-12-11 18:46:05 · 108 阅读 · 0 评论 -
拓扑排序
定义关于有向无环图的一种算法。实现Kahn 算法原理Kahn 算法实际上用的是贪心算法思想,思路非常简单、好懂。定义数据结构的时候,如果 s 需要先于 t 执行,那就添加一条 s 指向 t 的边。所以,如果某个顶点入度为 0, 也就表示,没有任何顶点必须先于这个顶点执行,那么这个顶点就可以执行了。我们先从图中,找出一个入度为 0 的顶点,将其输出到拓扑排序的结果序列中(对应代码...原创 2019-11-18 22:32:36 · 84 阅读 · 0 评论 -
动态规划
目标用来解决最优问题,如最大值,最小值等等。0-1背包代码实现package mainimport "fmt"var weight = []int{2,2,4,6,3}var maxBagWeight = 9var n = 5var maxResult int// 回溯思想实现func Bag(ci, cw int) { if ci == n || cw ...原创 2019-11-13 11:20:54 · 84 阅读 · 0 评论 -
回溯算法
思想笼统的讲,回溯算法主要应用在搜索问题中,这不是简单的图搜索等,主要是从一组可能的解中,寻找一组满足期望的解。回溯的处理思想,有点类似枚举搜索。我们枚举所有的解,找到满足期望的解。为了有规律地枚举所有可能的解,避免遗漏和重复,我们把问题求解的过程分为多个阶段。每个阶段,我们都会面对一个岔路口,我们先随意选一条路走,当发现这条路走不通的时候(不符合期望的解),就回退到上一个岔路口,另选一种...原创 2019-11-11 14:52:48 · 123 阅读 · 0 评论 -
贪心算法
哈夫曼树原理编码实现解码实现原创 2019-11-11 14:11:20 · 92 阅读 · 0 评论 -
敏感词过滤:AC自动机
单模式串匹配单模式串匹配是一个模式串,对应一个主串,即在一个主串中值查找这一个模式串;相关算法有:bf,rk,bm,kmp多模式串匹配多模式串为多个模式串跟一个主串查找匹配,即在一个主串中查找多个模式串;相关算法有:Trie树,AC自动机针对敏感词过滤,敏感词的集合即为模式串的集合,用户的输入为一个主串,所以在一个主串中查找多个模式串,这样用多模式串匹配比较高效。目标...原创 2019-11-07 15:35:00 · 463 阅读 · 0 评论 -
多模式字符串匹配:Trie树
Trie树定义Trie树,也叫“字典树”,是一种树形结构,专门用来处理字符串匹配的数据结构。Trie树的本质,利用字符串间的公共前缀,将重复的字符合并在一起,形成一个树形结构,并且给叶子节点打上标记。其中,根节点不包含任何信息,每个节点表示一个字符串中的一个字符,从根节点到叶子节点的一个路径,表示一个字符串。Trie树是一个多叉树。多叉树存储 todo实现插入字符串...原创 2019-11-07 10:34:05 · 578 阅读 · 0 评论 -
Trie树
相关概念主串模式串模式串<=主串常用算法BF原理我们在主串中,分别检查从0,1,2,....,到n-m位置的,n-m+1个字符串是否匹配。特点暴力匹配算法(最简单,最暴力的匹配算法),也叫朴素匹配算法。 因为简单,不容易出错,容易实现,所以比较常用,而且现实场景字符串长度并不会很长,而且比较过程中发现不匹配就可以推到主串下一个字符继续匹配了,所以算法的时...原创 2019-11-01 17:25:02 · 98 阅读 · 0 评论 -
图应用:微博系统中的好友关系
系统好友关系需求判断用户A是否关注B。 判断用户A是否是用户B的粉丝。 用户A关注用户B。 用户A取消关注B。 按照名称首字母排序,分页获取用户的粉丝列表。 按照名称首字母排序,分页获取用户的关注列表。方案因为社交网络是一张稀疏图,用邻接矩阵存储比较浪费空间,所以用邻接表存储。 用一个邻接表来存储这种有向图是不够的。我们去查找某个用户关注了哪些用户非常容易,但是如果要想知道某...原创 2019-10-29 16:44:22 · 447 阅读 · 1 评论 -
图-BFS-DFS
相关概念图顶点边度方向有向图入度出度无向图权重带权图无权图带权有向图带权无向图存储邻接矩阵简单,直观,但比较浪费空间。使用比较方便,空间换时间。邻接表存储比较节省空间,但是使用比较耗时。因为邻接矩阵是数组存储,邻接表是链表存储,不连续,不支持随机读取。想知道两个顶点间是否存在一条边,得遍历这两个点所有点,对比。优化:可...原创 2019-10-29 15:50:10 · 136 阅读 · 0 评论 -
堆
定义堆是一种特殊的树,满足以下两点要求的,我们称之为堆。堆是一个完全二叉树(完全二叉树的要求,除最后一层外,其他层的节点数都是满的,并且最后一层的节点都靠左排列)。 堆中每个节点的值,都必须大于(或等于)其子树中每个节点的值。对于每个节点都大于其子树节点值得堆(根节点最大)称为大顶堆,对每个节点都小于其子树接地那的堆(根节点最小)称为小顶堆。实现存储因为堆是完全二叉树,所以...原创 2019-10-25 22:48:08 · 133 阅读 · 0 评论 -
二叉查找树
定义二叉查找树具有特殊的结构,其任意一个节点,其左子树要小于其父节点,父节点小于其右子树的值。特点支持快速的查找,插入,删除。性质若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值; 任意节点的左、右子树也分别为二叉查找树; 没有键值相等的节点。代码实现package main...原创 2019-10-25 17:35:13 · 320 阅读 · 0 评论 -
全排列
回溯法package mainimport "fmt"func AllSort(arr []string) (res [][]string) { n := len(arr) if n <= 1 { return [][]string{arr} } for i := 0; i < n; i++ { header := arr[i] newArr := ...原创 2019-10-23 14:24:57 · 106 阅读 · 0 评论 -
二叉树
树相关概念父节点 子节点 兄弟节点 叶子节点 高度 深度 层二叉树顾名思义,每个节点最多只有两个“叉”,也就是两个子节点,分别为左子节点和右子节点。 其中要求是最多,可以只有一个子节点,或者没有子节点。满二叉树叶子节点都在底部,除叶子节点外,其他节点都有两个子节点的二叉树,叫满二叉树。完全二叉树叶子节点都在最后两层,最后一层叶子节点都靠左排列,并且除了最后...原创 2019-10-22 22:05:56 · 142 阅读 · 0 评论 -
哈希算法
原则从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法)。 对输入数据非常敏感,哪怕原始数据只修改了一个 Bit,最后得到的哈希值也大不相同。 散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小。 哈希算法的执行效率要尽量高效,针对较长的文本,也能快速地计算出哈希值。应用安全加密 唯一标识 数据校验 散列函数 负载均衡 数据分片 分布式存储...原创 2019-10-22 20:40:14 · 184 阅读 · 0 评论 -
散列表
定义一种k-v数据结构,用的是数组支持的按照下标随机访问数据,时间复杂度为O(1)的特性,算是数组的一种扩展,由数组演化而来。可以说没有数组,就没有散列表。组成key/关键字散列函数散列值散列函数基本要求散列函数计算得到的散列值必须是一个非负整数(因为数组下标从0开始)。 当key1==key2时,那么hash(key1)==hash(key2)。 当key1!...原创 2019-10-22 15:23:36 · 175 阅读 · 0 评论 -
跳表
定义链表加多级索引的结构,称为跳表。特点单链表是有序的,然后提升多层索引,提高查询效率。基于链表实现的二分查找。每两个节点会抽出一个节点作为上一级索引的节点,第k级索引的个数,是第k-1级索引个数的1/2,那么第k级索引的个数就是n/2^k。每两个节点会抽出一个节点作为上一级索引的节点,查询的时间复杂度为logn是基于链表实现的二分查找,主要利用了空间换时间的思路。...原创 2019-10-22 14:14:11 · 137 阅读 · 0 评论 -
复杂二分查找
二分查找变种查找第一个等于给定值的元素。 查找最后一个等于给定值的元素。 查找第一个大于等于给定值的元素。 查找最后一个小于等于给定制的元素。代码实现package mainimport "fmt"// 递归实现func BinarySearchRecursive(arr []int, item int) int { n := len(arr) if n < ...原创 2019-10-22 10:16:24 · 131 阅读 · 0 评论 -
简单二分查找
时间复杂度O(logn)代码实现简单(序列中不存在重复)二分查找的实现package mainimport "fmt"// 递归实现func BinarySearchRecursive(arr []int, item int) int { n := len(arr) if n < 1 { return -1 } return BinarySearch...原创 2019-10-21 16:52:48 · 101 阅读 · 0 评论 -
排序总结
算法对比算法 时间复杂度 是否稳定排序 是否原地排序 冒泡排序 O(n^2) 是 是 插入排序 O(n^2) 是 是 选择排序 O(n^2) 否 是 归并排序 O(nlogn) 是 否 快速排序 O(nlogn) 否 是 桶排序 O(n) 是 否...原创 2019-10-21 15:08:05 · 225 阅读 · 0 评论 -
线性排序
定义排序算法的时间复杂度是线性的O(n),所以称为线性排序。如:桶排序,计数排序,基数排序。这些排序算法之所以能做到O(n)级别,是因为他们非基于比较的排序算法,都不涉及元素之间的比较操作。对原始数据格式要求比较严格,如下将汇总每个算法的数据格式,及应用场景。桶排序核心思想将要排序的数据分散到几个有序的桶中,每个桶的数据在单独排序。桶内排完序后,在把每个桶的数据按照顺序取出...原创 2019-10-20 22:01:01 · 557 阅读 · 0 评论 -
归并和快速排序-Go版本
前言冒泡,插入,选择时间复杂度O(n^2),三者中插入比较常用。归并,快速排序时间复杂度O(nlogn),比插入更加受欢迎。五种排序最受欢迎的是快速排序,常用程度为:快速排序>归并排序>插入排序>冒泡排序>选择排序实现归并排序package mainimport "fmt"func MergeSort(arr []int) { n := ...原创 2019-10-20 19:48:41 · 122 阅读 · 0 评论 -
排序一
常见排序算法算法 时间复杂度 是否基于比较 冒泡,插入,选择 O(n^2) 是 O(nlogn) O(n) 排序算法分析执行效率最好,最坏,平均情况时间复杂度。 时间复杂度的系数,常数,低阶。 比较次数,交换(或移动)次数。内存消耗原地排序:特指空间复杂度为O(1)的排序算法。稳定性稳定的...原创 2019-10-17 18:39:29 · 78 阅读 · 0 评论 -
递归
递归三要素一个问题得解,可以分解为几个子问题的解。 这个问题与分解之后的子问题,除了数据规模不同,求解思路要完全一样。 存在递归终止条件。递归实现步骤根据把大问题分解为小问题得规律,找出递推公式,找到终止条件。 翻译成代码。举例假设有n个台阶,一步可以走1个台阶或者2个台阶,问走完n个台阶有多少种走法?package mainimport "fmt"func S...原创 2019-10-16 22:03:33 · 98 阅读 · 0 评论 -
栈
定义“栈”是一种“操作受限”即只允许在一端插入和删除数据的线性表;后进者先出,先进者后出。相较数组和链表,栈带来的只有限制;从功能上数组和链表可以取代栈,但是前者暴露了太多可操作接口,操作上确实灵活自由,但使用时比较不可控,自然也就更容易出错。分类顺序栈数组实现的栈链式栈链表实现相关操作入栈出栈代码实现package mainimport (...原创 2019-10-15 22:48:06 · 101 阅读 · 0 评论 -
链表
定义链表通常跟数组对比来讲,最大不同从底层的存储结构上:数组需要连续的内存空间,对内存的要求比较高。而链表恰恰相反,它并不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来。链表种类单链表头节点尾节点,尾节点的next指针指向null。双向链表每个节点相比单链表都多存储了一个前驱指针,比较耗费内存。但是比单链表更便捷的插入和删除操作(单项链表插入和删除需要...原创 2019-10-12 15:26:30 · 541 阅读 · 0 评论 -
学习算法心得
给自己一个计划,一个系统的学习算法的计划。给自己一个标记,标记自己学习算法的心路历程。以此来鞭策自己,步步前行,不要放弃和掉队。每次学习完,要认真总结一下,同时进行代码实现,汇总成一片博文来分享给大家,以此来形成自己的学习路线,和学习轨迹,主要还是让自己能够及时回顾审视自己的学习计划是否按照自己的初心去执行实现。接下来的一直到19年过年的这段时间,我会坚持1-2天(毕竟有时候工作太忙,...原创 2019-10-11 11:49:25 · 260 阅读 · 0 评论 -
数组
定义数组(Array)一种线性表数据结构。它用一组连续的内存空间,来存储具有相同类型的数据。特性支持随机访问根据下标随机访问的时间复杂度为O(1)缺陷删除或者插入元素为了保证内存连续性,需要做大量的数据搬移工作。插入优化技巧如果数组是又序的,那么插入到K位置时,就只能搬移K后面的元素依次向后移动一位。时间复杂度为 O(n)。 对与无序数组,仅做存储作用的,插入新元...原创 2019-10-11 18:35:46 · 129 阅读 · 0 评论