1️⃣ 线性数据结构之数组
线性数据结构强调存储与顺序
2️⃣ 数组的特性
- 储存在物理空间上是连续的
- 底层的数组长度是不可变的
- 数组的变量,指向了数组的第一个元素的位置
- 优点:查询性能好
- 缺点:
- 因为空间必须得是连续的,所以如果数组比较大,当系统的空间碎片比较多的时候,容易存不下
- 因为数组的长度是固定的,所以数组的内容难以被添加和删除
2️⃣ 数组的实际操作
// 声明一个数组let arr = [1, 2, 3, 4, 5];// 为数组最后一位添加一个数字 6arr.push(6);// 实际上是开辟了一个新的储存空间生成一个这样的数组 [1 , 2, 3, 4, 5, 6] 在赋值给 arrlet arr = [1, 2, 3, 4, 5, 6];
1️⃣ 线性数据结构之链表

2️⃣ 链表的特点
- 空间上不是连续的
- 每存放一个值,都要多开销一个引用空间
- 优点:
- 只要内存足够大,就能存的下,不用担心空间碎片的问题
- 链表的添加和删除非常的容易
- 缺点:
- 查询速度慢 ( 指查询某个位置 )
- 链表每一个节点都需要创建指向 next 的引用,浪费一些空间,当节点内数据越多的时候,这部分多开销的内存影响越少
// 链表结构var b = {value: 2,next: null,};var a = {value: 1,next: b,};console.log(a.next == b); // true
2️⃣ 创建一个单项链表
// 创建一个链表function Node(value) {this.value = value;this.next = null;}var a = new Node(1);var b = new Node(2);var c = new Node(3);a.next = b;b.next = c;c.next = null;console.log(a.value); // 1console.log(a.next.value); // 2console.log(a.next.next.value); // 3
2️⃣ 创建一个双向链表
双向链表的优点,无论给出哪一个节点,都能对整个链表进行遍历
双向链表的缺点,对耗费一个引用空间,而且构建起来比较复杂
function Node(value) {this.value;this.next = null;this.pre = null;}var node1 = new Node(1);var node2 = new Node(2);var node3 = new Node(3);var node4 = new Node(4);var node5 = new Node(5);node1.next = node2;node2.pre = node1;node2.next = node3;node3.pre = node2;node3.next = node4;node4.pre = node3;node4.next = node5;node5.pre = node4;
1️⃣ 线性数据结构的遍历
遍历:将一个集合中的每一个元素进行获取并查看
// 创建一个链表function Node(value) {this.value = value;this.next = null;}var a = new Node(1);var b = new Node(2);var c = new Node(3);a.next = b;b.next = c;c.next = null;function bianli(root) {var temp = root;while (true) {if (temp != null) {console.log(temp.value, temp);// 输出// 1 Node {// value: 1,// next: Node { value: 2, next: Node { value: 3, next: null } }// }// 2 Node { value: 2, next: Node { value: 3, next: null } }// 3 Node { value: 3, next: null }} else {break;}temp = temp.next;}}bianli(a);
1️⃣ 线性数据结构的递归
function Node(value) {this.value = value;this.next = null;}var a = new Node(1);var b = new Node(2);var c = new Node(3);a.next = b;b.next = c;c.next = null;function bianli(node) {if (node == null) return;console.log(node.value);// 输出// 1// 2// 3bianli(node.next)}bianli(a);
1️⃣ 链表的逆置
function Node(value) {this.value = value;this.next = null;}var a = new Node(1);var b = new Node(2);var c = new Node(3);a.next = b;b.next = c;c.next = null;// 链表递归函数function bianli(node) {if (node == null) return;console.log(node.value);bianli(node.next)}// 链表逆置函数function nizhi(node) {if (node.next.next == null) { // 代表当前节点事倒数第二个节点node.next.next = node; // 让最后一个节点指向自己 ( 倒数第二个节点 )return node.next;} else {var result = nizhi(node.next);node.next.next = node;node.next = null;return result;}}bianli(a);/** 1* 2* 3*/nizhi(a) // 执行链表逆置的函数bianli(c);/** 3* 2* 1*/
