简单数据结构与简单算法

数据结构:数据用什么样的方式组合在一起

数据存储的常用结构有:栈、队列、数组、链表和红黑树

stack,又称堆栈。

栈只有一个出口,且先进后出(想象一下弹夹),只能从出口位置操作元素,不能从中间位置操作。

队列

queue,队列,先进先出。(想象一下火车过山洞)

数组

使用连续的内存来存储、数组中的所有元素都是相同的类型或类型的衍生(同质数据结构)、元素可以通过下标(索引)直接访问

特点是:查询快(有索引),增删慢

指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置

链表 LinkedList

单向链表

增删快(把两个节点断开,插入新的节点就可以了),查询慢

链表本身是无序的。

由两部分组成:数据域和指针域,每个结点都有一个指针,每个节点指针的指向都是指向自身结点的下一个结点,最后一个结点的head指向为null,对单链表的操作只能从一端开始,如果需要查找链表中的某一个结点,则需要从头开始进行遍历。

双向链表 doubly-linked-list

对于双向链表来说,它的每个节点要指向“直接前驱”和“直接后继”,所以节点类需要含有两个指针域。指向直接前驱的指针使用pre表示,指向后继的指针使用next表示。双向链表是在单向链表基础上的一个改进,每个节点指向其直接前驱和直接后继节点。因此,从双向链表的任意位置开始,都能访问所有的节点。同时也可以保证元素存入和取出的顺序是一致的

双向链表从节点的结构上可以看出,双向链表的所需的存储空间大于单向链表。同时,对于插入和删除等操作来说,双向链表的节点操作更加复杂,涉及到节点的前后两个节点。

二叉树 binary tree

二叉树是每个节点最多有两个子树的树结构。顶上的叫根结点,两边被称作“左子树”和“右子树”。

在这里插入图片描述

红黑树

红黑树可以通过红色节点和黑色节点尽可能的保证二叉树的平衡,从而来提高效率。

在这里插入图片描述
图片上的字实在是太小了,为方便以后好看,在下面写一下吧

  • 第二张图

    排序时,查找时
    在二叉树的基础上,元素是有大小顺序的
    左子树元素小,右子树元素大

    平衡树
    它的左右两个子树的高度差的绝对值不超过1,
    并且左右两个子树都是一棵平衡二叉树

  • 第三张图左边

    不平衡树

    高度差值大于1

    注意:
    在动态插入过程中如果需要保证树的完美平衡,代价过高
    但是我们又想要保证查询速度快,那么尽量要保证二叉树的平衡

  • 第三张图右边

    红黑树

    趋近于平衡树,查询的速度非常快
    查询叶子节点的最大次数和最小次数不能超过2倍

    红黑树的约束:
    1.根节点/空节点是黑色的,其他节点可以是红色的或者黑色的
    2.每个红色节点的子节点都是黑色的
    3.任何一个节点到其每一个叶子节点的所有路径上黑色节点数相同

    通过红黑树的约束
    保证最大路径不超过最小路径的2倍,来尽量保证红黑树的平衡

哈希表

哈希表(hash table,也叫散列表),是根据关键码值(key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫散列函数,存放记录的数组叫散列表

实际上哈希表就是模拟的数组,只不过数组中的每一个元素又是链表。

在Java中,像HashSet,HashMap等集合的底层数据结构都使用了哈希表,哈希表利用了数组支持按照下标访问的特性,因此散列表类似于一种数组的扩展,在JDK1.8及以后,它由数组+链表/红黑树构成。

哈希表的优势在于:查询速度快,不需要从头开始差,而只需要通过key的值去定位数据所在的链表(Java集合中的hashmap,hashset底层都是通过这样一个哈希表来实现的)。

数组更利于元素的查找;
链表更利于元素的插入和删除;

希表是由一块地址连续的数组空间构成的,其中每个数组都是一个链表,数组的作用在于快速寻址查找,链表的作用在于快速插入和删除元素,因此,哈希表可以被认为就是链表的数组。

!重点:如何判断新增的两个元素是否重复

比较两个对象的哈希值&&(地址值相同||equals相同)

新增过程:

  1. 计算新增元素的哈希值(hashcode)

  2. 通过hash%数组长度获取索引值(0-15)

  3. 如果该位置为null,则直接新增

    如果该位置不为null,则判断是否重复(equals());

    • 如果不重复则新增到该索引值位置链表的最后面

    • 如果重复则不新增

哈希表的扩容:当哈希表被占的位置比较多的时候,出现哈希冲突的概率也就变高了,所以很有必要进行扩容。

newCapacity = oldCapacity+(oldCapcity>>1)

新容量等于旧容量的1.5倍

哈希表的内存结构示意图

在散列表中,不像普通数组,每个格子里存放的是一个单一的数据,而是在每一个格子中存放的是一个链表。如图:

在这里插入图片描述

JDK1.8 的哈希冲突解决方案

JDK1.8 中的哈希表是使用链表+红黑树解决哈希冲突。

默认使用单向链表将元素串起来。
每次都是从头节点开始遍历;单向链表比双向链表少一个指针,可以节省内存空间。

在添加元素时,可能会由单向链表转为红黑树来存储元素。
比如当哈希表容量 ≥ 64 且 单向链表的节点数量大于 8 时。

当红黑树节点数量少到一定程度时,又会转为单向链表。

在这里插入图片描述

简单算法

二分查找

二分查找(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它的工作原理是通过不断地将搜索范围缩小一半来找到目标元素。具体步骤如下:

首先,从数组的中间元素开始搜索。
如果中间元素正好是要查找的元素,则搜索过程结束。
如果某一特定元素大于中间元素,则在数组的右半部分继续搜索。
如果某一特定元素小于中间元素,则在数组的左半部分继续搜索。
重复以上步骤,直到找到目标元素或者搜索范围为空(即找不到目标元素)。

二分查找的时间复杂度是O(logn),其中n是要搜索的数组的大小。这是因为每次比较都会将搜索范围缩小一半,因此查找的次数与log2(n)成正比。这种算法在处理大量数据时具有较高的效率。

二分查找的实现可以涉及多种编程语言,例如C#、Java等。代码示例展示了如何在C#中实现二分查找算法。此外,二分查找也被称为折半查找或对数搜索,这些名称都指的是同一种算法,只是在不同的语境或文献中表述不同。

部分内容转载自:
https://www.cnblogs.com/joion/p/13646815.html
https://blog.csdn.net/sheng0113/article/details/122781495
https://juejin.cn/post/6976994044928851975

理解历史人物,就是理解现在的人物。

当年明月

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值