a[1]
方括号表示存储地址的偏移 操作系统中:通过偏移查询数据性能最好
数组
特性:
- 存储在物理空间上是连续的
- 底层的数组长度是不可变的
- 数组的变量,指向了数组第一个元素的位置
优点:
查询性能好
缺点:
- 因为空间必须是连续的,如果数组较大,当系统空间碎片较多,容易存不下
- 因为数组长度固定,所以数组长度难以添加或删除
链表
特点:
空间上不连续
每存放一个值,就要多开销一个引用空间
优点:
- 只要内存足够大,就能存的下,不用担心空间碎片问题
- 链表中添加删除比较容易
想传递一个链表,必须传递链表的根节点
每个节点都认为自己是根节点
缺点:
查询速度慢
链表每一个节点都需要创建一个指向next的引用,浪费一些空间
当节点内数据越多时,这部分多开销的内存影响越少
function Node (value) {
this.value = value
this.next = null
}
var a = new Node(1)
var b = new Node(2)
var c = new Node(3)
var d = new Node(4)
a.next = b
b.next = c
c.next = d
d.next = null
console.log(a.value)
console.log(a.next.next.value)
console.log(a.next.next.next.value)
遍历:
对一个集合中的每一个元素获取并查看
链表:
链表遍历
function linkList (root) {
var temp = root
while (true) {
if (temp != null) {
console.log(temp.value)
} else {
break
}
temp = temp.next
}
}
console.log(linkList(a))
链表递归
function linkList (root) {
if (root == null) return//递归遍历必须有出口
console.log(root.value)
linkList(root.next)
}
linkList(a)
数组:
遍历数组
算法题,一定要判断数组是否为空 否则array.length会报错
const arr = [3, 4, 1, 7, 3, 7, 9]
function ArrayList (arr) {
if (arr == null) return
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
}
ArrayList(arr)
数组递归
function ArrayList(arr ,i){
if(arr==null||i>=arr.length) return
console.log(arr[i])
ArrayList(arr,i+1)
}
ArrayList(arr,0)
链表
逆置
1.拿到最后一个节点
function InversionLinkList (root) {
if (root.next != null) {
return InversionLinkList(root.next)
} else {
return root
}
}
console.log(InversionLinkList(node1))
function InversionLinkList (root) {
// console.log(root, 'root')
if (root.next.next == null) {//代表当前节点为倒数第二个节点
console.log('倒数第二个节点', root)
root.next.next = root //让最后一个节点指向自己(倒数第二个节点)
return root.next
} else {
var result = InversionLinkList(root.next)
console.log('root', root)
root.next.next = root
root.next = null
return result
}
}
var newLink = InversionLinkList(node1)
console.log('newLink是', newLink)
数组排序
冒泡排序
const arr = [3, 4, 1, 7, 2, 8, 9]
function compare (a, b) {
// return a - b//数组逆序 [9, 8, 2, 7, 1, 4, 3]
return a - b > 0 ? true : false//数组排序 [9, 8, 2, 7, 1, 4, 3]
}
function exchange (arr, a, b) {//数组中a b位置进行交换
[arr[b], arr[a]] = [arr[a], arr[b]]//解构赋值
}
function bubbleSort (arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - 1 - i; j++) {
console.log(j, arr[j], arr[j + 1])
if (compare(arr[j], arr[j + 1])) {
exchange(arr, j, j + 1)
}
}
}
return arr
}
console.log(bubbleSort(arr))
选择排序
// 选择排序,内层循环,每一圈选出一个最大的,然后放在后面
function Sort (arr) {
for (let i = 0; i < arr.length; i++) {
var maxIndex = 0
console.log('i------>', i)
for (let j = 0; j < arr.length - i; j++) {
console.log(j, arr[j])
if (compare(arr[maxIndex], arr[j])) {
// console.log(j)
maxIndex = j
}
}
exchange(arr, maxIndex, arr.length - 1 - i)
}
return arr
}
function compare (a, b) {
// return a - b
return a - b < 0 ? true : false//数组排序 [9, 8, 2, 7, 1, 4, 3]
}
简单快速排序
const arr = [3, 4, 1, 7, 2, 8, 9, 6, 10, 22, 17]
function quickSort (arr) {
if (arr == null || arr.length == 0) {
return []
}
var leader = arr[0]
//小的站在左边,大的站在右边
var left = []
var right = []
for (var i = 1; i < arr.length; i++) {
if (arr[i] < leader) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
left = quickSort(left)
right = quickSort(right)
left.push(leader)
return left.concat(right)
}
console.log(quickSort(arr))//(11) [1, 2, 3, 4, 6, 7, 8, 9, 10, 17, 22]
标准快速排序?????
function sort (arr, begin, end) {
if (begin >= end - 1) return
var left = begin
var right = end
console.log(arr[left], arr[begin])
do {
do left++; while (left < right && arr[left] < arr[begin])
do right++; while (left > right && arr[right] > arr[begin])
if (left < right) swap(arr, left, right)
} while (left < right)
}
function quickSort (arr) {
sort(arr, 0, arr.length - 1)
}
console.log(quickSort(arr))
栈
var arr = []
function Stack () {
this.arr = []
this.push = function (value) {
this.arr.push(value)
}
this.pop = function () {
this.arr.pop()
}
}
var stack = new Stack()
stack.push(1)
stack.push(2)
stack.push(3)
console.log(stack.arr)
stack.pop()
console.log(stack.arr)
队列
function Queue () {
this.arr = []
// 入队
this.push = function (value) {
this.arr.push(value)
}
// 出队
this.pop = function () {
return this.arr.shift()
}
}
var queue = new Queue()
queue.push(1)
queue.push(2)
queue.push(3)
console.log(queue.arr)
queue.pop()
console.log(queue.arr)
双向链表(不重要)
优点:
无论给出哪一个节点,都能对整个链表进行遍历
缺点:
多耗费一个引用空间,构建双向链表比较复杂
function Node (value) {
this.value = 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