数据结构的分类
常见的数据结构:树、链表、栈、图、顺序表、堆、哈希表
按逻辑结果分:线性数据结构、非线性数据结构
线性数据结构:链表、顺序表、栈
非线性数据结构:树、图、堆、哈希表
非线性结构又可以分为:
树形结构:树、堆、哈希表,元素之间时一对多的关系
网状结构:图、元素之间时多对多的关系
物理结构反映了数据在计算机内存中的存储方式,可分为连续空间存储(数组)和分散空间存储(链表)。
数字编码
数字是以“补码”的形式存储在计算机中的
- 原码:我们将数字的二进制表示的最高位视为符号位,其中 0 表示正数,1 表示负数,其余位表示数字的值。
- 反码:正数的反码与其原码相同,负数的反码是对其原码除符号位外的所有位取反。
- 补码:正数的补码与其原码相同,负数的补码是在其反码的基础上加
原码虽然直观,但不能直接参与运算,与负数相加时因为最高位的符号位会产生错误
如1+(-2) = -3
0000 0001 + 1000 0010 = 1000 0011 ( - 3 )
为了解决这个问题提出了反码的概念
个人理解:如果正数比负数小,整数的反码仍是原码,负数的反码是原码的除了符号位全部取反
二者的二进制相加相当于将正数中为1的位和负数相同位置的位加起来,如果负数反码位上为0,加起来位置为一之后取反就相当于负数的大小减去了正数其位上表示的数,如果负数反码位上为1,说明负数原码次位上为0是没有这个数的,按照正常的减法,得向上一位借1,故加起来,上一位置为1,取反为0相当于减去这个位上表示的大小,相加的位置为0取反后表示,向前借的位表示的数减去正数之后剩下的数是正数位上的数(如1000 - 0100 =0100 0100 -0010 = 0010)。
如果负数比正数小,因为符号位为1,而负数比正数小,取反后加上正数的肯定会进1导致符号位会变为0,相加结果的符号位为0为正数取反后仍是原来的数,故加上负数反码上为1的位,如果进位说明正数位上有这个数,不用向上一位借,直接减去置为0,如果不进位,表示没有这个数,需借上一位,导致上一位不会进位,所以上一位的位在结果上会为0。
0000 1101 13 1000 0010 -2 0000 1001 9 1000 0010 -2
0000 1101 0000 1001 9
1111 1101 1111 1101
0000 1001 9 0000 0101 7 因为没进1,导致上一位的位结果为0,被借走了
先将负数原码转为反码,加上正数后再取反为结果。
数字零的原码有 +0 和 −0 两种表示方式。这意味着数字零对应两个不同的二进制编码,这可能会带来歧义。比如在条件判断中,如果没有区分正零和负零,则可能会导致判断结果出错。而如果我们想处理正零和负零歧义,则需要引入额外的判断操作,这可能会降低计算机的运算效率。
反码也存在正负零歧义问题,因此计算机进一步引入了补码。
在负零的反码基础上加 1 会产生进位,但 byte
类型的长度只有 8 位,因此溢出到第 9 位的 1 会被舍弃。也就是说,负零的补码为 00000000 ,与正零的补码相同。这意味着在补码表示中只存在一个零,正负零歧义从而得到解决。
正数的补码等于本身,负数的补码等于反码+1。
反码加一”只是补码所具有的一个性质,不能被定义成补码。负数的补码,是能够和其相反数相加通过溢出从而使计算机内计算结果变为0的二进制码。