数据结构——数组、链表、栈

本文探讨了数组和链表在操作系统中的存储特性、查询性能、空间利用以及增删操作的优缺点,包括数组的连续性、链表的灵活性和递归遍历方法。同时介绍了数组排序(冒泡、选择、快速排序)和基本的数据结构如栈和队列的实现。
摘要由CSDN通过智能技术生成

a[1]

方括号表示存储地址的偏移 操作系统中:通过偏移查询数据性能最好

数组

特性:

  1. 存储在物理空间上是连续的
  2. 底层的数组长度是不可变的
  3. 数组的变量,指向了数组第一个元素的位置

优点:

查询性能好

缺点:

  1. 因为空间必须是连续的,如果数组较大,当系统空间碎片较多,容易存不下
  2. 因为数组长度固定,所以数组长度难以添加或删除

链表

特点:

空间上不连续

每存放一个值,就要多开销一个引用空间

优点:

  1. 只要内存足够大,就能存的下,不用担心空间碎片问题
  2. 链表中添加删除比较容易

想传递一个链表,必须传递链表的根节点

每个节点都认为自己是根节点

缺点:

查询速度慢 

链表每一个节点都需要创建一个指向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

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值