数据结构-数组&链表

数组

用一组连续的内存空间,来存储一组具有相同类型的数据。

数组特性

  1. 数组中各个元素是有先后顺序的,在内存按照这个顺序连续存放在一起
  2. 相同类型的数据
  3. 支持随机访问,查找快
  4. 插入删除慢,因为要维护数组的连续性
  5. 数组下标可以表示有意义的数据

动态数组

当存不下新元素是,需要扩容数组:

  1. 重新开辟一块大小为当前容量两倍的数组
  2. 拷贝原数据
  3. 删除原数组

ArrayList与数组

ArrayList,由JDK封装,底层使用数组实现,不需要自实现扩容等操作。

如何选用

  1. 不知道数据大小的时候选ArrayList
  2. 知道数据大小,要求性能高,选用数组

注意点

数组最需要注意的是越界,尤其是头尾,需要更多关注。

堆栈内存

new创建出来的对象和数组存放在堆内存中。

堆栈区别

  1. 栈的速度更快
  2. 栈内存中的数据可以共享,主要存一些基本数据类型
    int a = 3; //在栈中创建变量a 然后给a赋值,先不会创建一个3而是先在栈中找有没有3,如果有直接指向。如果没有就加一个3进来。

堆栈试题

String s1 = "a";
String s2 = "a";
System.out.println(s1 == s2);
/*结果:true
s1与s2指向同一个对象,在栈中的“a”
*/
String s1 = "a";
String s2 = "a";
s1 = "b";
System.out.println(s1 + s2);//ba
System.out.println(s1 == s2);//false
/*虽然s1与s2都指向同一个变量"a",但s1引用变化后不会改变s2的值
*/
String s1 = new String("a");
String s2 = "a";
System.out.println(s1 == s2);
/*结果:false
new的对象存放在堆中,s2的“a”存放在栈中。
*/
String s1 = "ja";
String s1 = "va";
String s3 = "java";
String s4 = s1 + s2;
System.out.println(s3 == s4);
/*结果:false
因为Java重载了+,当你使用“+”时,其实调用了StringBuild,会new对象。
*/

数组下标为什么从“0”开始

数组的内存空间是连续的。

int a[] = new int[3];

比如a数组内存地址为1001,1002,1003
内存寻址如下:
数组下标从0开始
a[0] => 1001 ==> 1001 + 0 * 4byte
a[1] => 1002 ==> 1001 + 1 * 4byte
a[2] => 1003 ==> 1001 + 2 * 4byte
数组下标从1开始
a[1] => 1001 ==> 1001 + (1-1) * 4byte
a[2] => 1002 ==> 1001 + (2-1) * 4byte
a[3] => 1003 ==> 1001 + (3-1) * 4byte
需要多一次减运算。

二维数组

int a[][] = new int[5][5];
/*
a[3][2]的内存寻址公式=(3*5+2) * 4byte
a[i][j] = (i*n+j) * 4byte(数据类型大小)
*/

链表

链表是一种物理上地址非连续、非顺序的存储结构,由一系列节点组成,每个节点包括两个部分:

  1. 存储数据的数据域
  2. 存储下一个节点地址的指针

链表结构

单向链表

单向链表结构
head头节点需要自己记录
tail尾节点下一个节点指向null

插入与删除

双向链表

循环链表

链表特性

  1. 不需要连续的内存空间
  2. 有指针

Java中链表的应用

双向链表LinkedList
JDK1.7&1.8中的List
JDK1.7中的HashMap:数组+链表
JDK1.8中的HashMap:红黑树

LRU缓存淘汰算法

缓存最新使用的
使用链表实现:

  1. 在链表里查找,如果找到了,就删除,然后把新的节点插入到头部;
  2. 不在链表里,有空间就插入头部,没有空间就删除最后一个节点然后再插入头部;
  3. 链表要有大小限制。

约瑟夫问题

使用单循环链表实现。

链表与数组

区别

  1. 数组使用连续的内存空间,可以借助CPU缓存机制,预读数组中的数据,访问效率更高。

    链表没有使用连续的内存空间,没有办法预读数据。

  2. 数组大小固定,新建的时候就占用整块连续的内存空间,数组过大,系统可能没有足够的连续内存空间分配,数组过小,可能会出现不够用的情况,需要动态扩容。

    而链表没有大小限制,天然支持动态扩容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cuidianjay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值