今天来聊聊数据结构中的算法结构-链表
相较于之前学习的 栈/队列 只关心 栈顶/首尾 的模式,链表更加像是数组。链表和数组都是用于存储有序元素的集合,但有几点大不相同
链表不同于数组,链表中的元素在内存中并不是连续放置的 链表添加或移除元素不需要移动其他元素 数组可以直接访问任何一个位置的元素,链表必须从表头开始迭代到指定位置访问。
- 链表几乎可以用在任何可以使用一维数组的情况中。如果需要随机访问,数组仍然是更好的选择
数据查询
链表要想随机访问第 k 个元素,就没有数组那么高效了。因为链表中的数据并非连续存储的,所以无法像数组那样,根据首地址和下标,通过寻址公式就能直接计算出对应的内存地址,而是需要根据指针一个结点一个结点地依次遍历,直到找到相应的结点。
时间复杂度为O(n)
代码实现
var Node = function (el) {
this.el = el
this.next = null
}
首先要定义描述每个节点的node,他的属性描述了下个节点的链接
我们先来实现他的添加功能的方法(这里先贴代码了)
var likedlist=function(){
var head = null
var length = 0
var Node = function (el) {
this.el = el
this.next = null
}
// 链表添加元素
this.append = function (el) {
var node = new Node(el)
if (head == null) {
head = node
}
else {
var current = head
while (current.next) {
current = current.next
}
// while循环执行完已经是最后一项了
current.next = node
}
length++
}
}
先实例化一个节点对象,对象都有一条指向下一个节点的链接状态,是null 还是 下个节点node,这个先判断链头有没有元素,没有的话,就把第一个添加进来的node当做head头,当添加第二个已经有head,这时用while循环遍历对象的next属性,这个next就是链接两个node的纽带,只要添加下个node时,就先看看上个next的状态是不是为null,如果是的话,就把下个节点的引用给到上个节点的next,每添加一个都会进行这样的状态。这样我们就完成了添加的操作
插入的操作
再来添加插入的操作
this.insert = function (position, el) {
if (position > -1 && position < length) {
var node = new Node(el)
if (position === 0) {
var current = head
head = node
head.next = current
}
else {
var index = 0
var current = head
var previous = null
while (index === position) {
previous = current
current = current.next
index++
}
previous.next = node
node.next = current
}
length++
}
}
第一块先要判断临界值,判断是否在链表的范围内及是否添加链表头部,如果不是的话 添加元素到position 后面
删除节点
this.removeAt = function (position) {
if (position > -1 && position < length) {
if (position === 0) {
var current = head
head = current.next
}
else {
var current = head,
privious = null,
index = 0
//循环列表,找到position位置的元素和前一个元素
while (index < position) {
privious = current
current = current.next
index++
}
//跳出循环的时候,index===position
}
index--
return current
}
return
}
获取链表头
this.getHead = function () {
return head
}
判断链表是否为空
this.isEmpty = function () {
return !!length
}
最后贴下代码
//链表
//每个元素都带有下个元素的位置,链表就像火车,每个车厢不仅会有自己的乘客,而且还与链节下节车厢
var likedlist = function () {
var head = null
var length = 0
var Node = function (el) {
this.el = el
this.next = null
}
// 链表添加元素
this.append = function (el) {
var node = new Node(el)
if (head == null) {
head = node
}
else {
var current = head
while (current.next) {
current = current.next
}
// while循环执行完已经是最后一项了
current.next = node
}
length++
}
this.insert = function (position, el) {
if (position > -1 && position < length) {
var node = new Node(el)
if (position === 0) {
var current = head
head = node
head.next = current
}
else {
var index = 0
var current = head
var previous = null
while (index === position) {
previous = current
current = current.next
index++
}
previous.next = node
node.next = current
}
length++
}
}
this.isEmpty = function () {
return !!length
}
this.removeAt = function (position) {
if (position > -1 && position < length) {
if (position === 0) {
var current = head
head = current.next
}
else {
var current = head,
privious = null,
index = 0
while (index < position) {
privious = current
current = current.next
index++
}
//跳出循环的时候,index===position
}
index--
return current
}
return
}
this.getHead = function () {
return head
}
}
总结:
要存储多个元素,数组可能是最常用的数据结构。但是,如果要存储数据,并且会有移除或者添加大量数据时候,链表比数组更实用。