1、数据结构的存储方式
数据结构的存储方式只有两种:数组(顺序存储)和链表(链式存储)
。
散列表、栈、队列、堆、树、图等等各种数据结构,其基础存储结构都是从数组或链表实现而来的
用数组实现,就要处理扩容缩容的问题;
用链表实现,没有这个问题, 但需要更多的内存空间存储节点指针。
数组 访问快,修改慢
链表 访问慢,修改快
数组由于是紧凑连续存储,可以随机访问,通过索引快速找到对应元素,而且相对节约存储空间。
但正因为连续存储,内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去,时间复杂度O(N);
而且你如果想在数组中间进行插入和删除,每次必须搬移后面的所有数据以保持连续,时间复杂度 O(N)。
但正因为连续存储,内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去,时间复杂度O(N);
而且你如果想在数组中间进行插入和删除,每次必须搬移后面的所有数据以保持连续,时间复杂度 O(N)。
链表因为元素不连续,而是靠指针指向下一个元素的位置,所以不存在数组 的扩容问题;
如果知道某一元素的前驱和后驱,操作指针即可删除该元素或者插入新元素,时间复杂度 O(1)
。
但是正因为存储空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问;
而且由于每个元素必须存储指向前后元素位置的指针,会消耗相对更多的储存空间。
2、数据结构的基本操作
对于任何数据结构,其基本操作无非是遍历
+
访问,再具体一点就是:增删查改。
数据结构种类很多,但它们存在的目的都是在不同的应用场景,尽可能高效
地增删查改
。
数组遍历框架
package com.arrayDemo;
/*
* 数组遍历框架
*/
public class arrDemo {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
arrDemo.traverse(arr);
}
public static void traverse(int[] arr) {
for (int i = 0; i < arr.length; i++) {
//迭代访问 arr[i]
//do something
System.out.println(arr[i]);
}
}
}
链表遍历框架
链表类
package com.arrayDemo;
/*
* 链表类
*/
public class linkDemo {
int var;
linkDemo next;
linkDemo(int var,linkDemo next) {
this.var = var;
this.next = next;
}
public void traverse(linkDemo head) {
for (linkDemo p = head; p != null; p = p.next) {
//迭代访问 p.val
//do something
System.out.println(p.var);
}
}
}
链表遍历测试
package com.arrayDemo;
/*
* 链表遍历测试
*/
public class linkDemoTest {
public static void main(String[] args) {
linkDemo l1 = new linkDemo(1, null);
linkDemo l2 = new linkDemo(2, null);
linkDemo l3 = new linkDemo(3, null);
linkDemo l4 = new linkDemo(4, null);
linkDemo l5 = new linkDemo(5, null);
l1.next = l2;
l2.next = l3;
l3.next = l4;
l4.next = l5;
l1.traverse(l1);
}
}