新闻、帮助、产品更新动态

最新的业界新闻,产品系统更新开发动态,帮助教程和活动发布

万字长文带你漫游数据结构世界(一)位

发布日:2022-01-13 10:12       阅读数:

数据结构是什么?

程序 = 数据结构 + 算法
 
是的,上面这句话是非常经典的,程序由数据结构以及算法组成,当然数据结构和算法也是相辅相成的,不能完全独立来看待,但是本文会相对重点聊聊那些常用的数据结构。

数据结构是什么呢?

首先得知道数据是什么?数据是对客观事务的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号总称。那为何加上“结构”两字?
数据元素是数据的基本单位,而任何问题中,数据元素都不是独立存在的,它们之间总是存在着某种关系,这种数据元素之间的关系我们称之为结构。
因此,我们有了以下定义:
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
简单讲,数据结构就是组织,管理以及存储数据的方式。虽然理论上所有的数据都可以混杂,或者糅合,或者饥不择食,随便存储,但是计算机是追求高效的,如果我们能了解数据结构,找到较为适合当前问题场景的数据结构,将数据之间的关系表现在存储上,计算的时候可以较为高效的利用适配的算法,那么程序的运行效率肯定也会有所提高。
常用的4种数据结构有:
集合:只有同属于一个集合的关系,没有其他关系
线性结构:结构中的数据元素之间存在一个对一个的关系
树形结构:结构中的数据元素之间存在一个对多个的关系
图状结构或者网状结构:图状结构或者网状结构

何为逻辑结构和存储结构?

数据元素之间的逻辑关系,称之为逻辑结构,也就是我们定义了对操作对象的一种数学描述。但是我们还必须知道在计算机中如何表示它。数据结构在计算机中的表示(又称为映像),称之为数据的物理结构,又称存储结构。
数据元素之前的关系在计算机中有两种不同的表示方法:顺序映像和非顺序映像,并且由此得到两种不同的存储结构:顺序存储结构和链式存储结构,比如顺序存储结构,我们要表示复数z1 =3.0 - 2.3i,可以直接借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系:

而链式结构,则是以指针表示数据元素之间的逻辑关系,同样是z1 =3.0 - 2.3i,先找到下一个是 100,是一个地址,根据地址找到真实的数据-2.3i:



位(bit)

在计算机中表示信息的最小的单位是二进制数中的一位,叫做位。也就是我们常见的类似01010101010这种数据,计算机的底层就是各种晶体管,电路板,所以不管是什么数据,即使是图片,声音,在最底层也是0和1,如果有八条电路,那么每条电路有自己的闭合状态,有8个2相乘,2^8^,也就是256种不同的信号。

 
但是一般我们需要表示负数,也就是最高的一位表示符号位,0表示正数,1表示负数,也就是8位的最大值是01111111,也就是127。
 
值得我们注意的是,计算机的世界里,多了原码,反码,补码的概念:
 
原码:用第一位表示符号,其余位表示值
反码:正数的补码反码是其本身,负数的反码是符号位保持不变,其余位取反。
补码:正数的补码是其本身,负数的补码是在其反码的基础上 + 1
为什么有了原码还要反码和补码?
我们知道加减法是高频的运算,人可以很直观的看出加号减号,马上就可以算出来,但是计算机如果区分不同的符号,那么加减就会比较复杂,比如正数+正数,正数-正数,正数-负数,负数+负数...等等。于是,有人就想用同一个运算器(加号运算器),解决所有的加减法计算,可以减少很多复杂的电路,以及各种符号转换的开销,计算也更加高效。
 
我们可以看到,下面负数参加运算的结果也是符合补码的规则的:
 00100011		35
 +      11011101	   -35
-------------------------
        00000000       0
        00100011		35
 + 	    11011011	   -37
-------------------------
        11111110       -2
当然,如果计算结果超出了位数所能表示的范围,那就是溢出,就说明需要更多的位数才能正确表示。
 
一般能用位运算的,都尽量使用位运算,因为它比较高效, 常见的位运算:
 
~:按位取反
&:按为与运算
|:按位或运算
^:按位异或
<<: 带符号左移,比如35(00100011),左移一位为 70(01000110),-35(11011101)左移一位为-70(10111010)
>>:带符号右移,比如35(00100011),右移一位为 17(00010001),-35(11011101)左移一位为-18(11101110)
<<<:无符号左移,比如35(00100011),左移一位为70(01000110)
>>>:无符号右移,比如-35(11011101),右移一位为110(01101110)
x ^= y; y ^= x; x ^= y;:交换
s &= ~(1 << k):第k位置0
要说哪里使用位运算比较经典,那么要数布隆过滤器,需要了解详情的可以参考:http://aphysia.cn/archives/cachebloomfilter

布隆过滤器是什么呢?

布隆过滤器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的,它实际上是由一个很长的二进制向量和一系列随机hash映射函数组成(说白了,就是用二进制数组存储数据的特征)。可以使用它来判断一个元素是否存在于集合中,它的优点在于查询效率高,空间小,缺点是存在一定的误差,以及我们想要剔除元素的时候,可能会相互影响。

也就是当一个元素被加入集合的时候,通过多个hash函数,将元素映射到位数组中的k个点,置为1

重点是多个hash函数,可以将数据hash到不同的位上,也只有这些位全部为1的时候,我们才能判断该数据已经存在

假设有三个hash函数,那么不同的元素,都会使用三个hash函数,hash到三个位置上。

假设后面又来了一个张三,那么在hash的时候,同样会hash到以下位置,所有位都是1,我们就可以说张三已经存在在里面了。

后面来了陈六,但是不凑巧的是,它hash的三个函数hash出来的位,刚刚好就是被别的元素hash之后,改成1了,判断它已经存在了,但是实际上,陈六之前是不存在的。

上面的情况,就是误判,布隆过滤器都会不可避免的出现误判。但是它有一个好处是,布隆过滤器,判断存在的元素,可能不存在,但是判断不存在的元素,一定不存在。,因为判断不存在说明至少有一位hash出来是对不上的。

也是由于会出现多个元素可能hash到一起,但有一个数据被踢出了集合,我们想把它映射的位,置为0,相当于删除该数据。这个时候,就会影响到其他的元素,可能会把别的元素映射的位,置为了0。这也就是为什么布隆过滤器不能删除的原因。

编辑:航网科技   来源:腾讯云

本文版权归原作者所有 转载请注明出处

联系我们

0755-36300002

深圳市龙华区和平路龙胜商业大厦5楼B5区

资质证书

  • Copyright © 2011-2020 www.hangw.com. All Rights Reserved 深圳航网科技有限公司 版权所有 增值电信业务经营许可证:粤B2-20201122 - 粤ICP备14085080号

    在线客服

    微信扫一扫咨询客服


    全国免费服务热线
    0755-36300002

    返回顶部