链表(线性结构)
链表中的元素在内存中不必是连续的空间,实现灵活的内存动态管理;不必在创建的时候确定大小,大小可以无限延申;链表在插入和删除数据时,时间复杂度可以达到O(1),非常高效;但是链表访问任何一个位置的元素时,都需要从头开始访问
单向链表的封装
里面封装了多种方法,都添加了注释
function linkedList() {
//内部的类 这里可以在参数里面传next也可以不传
function Node(data) {
this.data = data;
this.next = null;
}
this.head = null;
this.length = 0;
//1.追加方法
linkedList.prototype.append = function(data) {
//创建新节点
var newNode = new Node(data);
//判断添加的是否是第一个节点
if (this.length == 0) {
this.head = newNode;
}
//不是第一个节点
else {
var current = this.head;
//找到最后一个节点
while (current.next) {
current = current.next;
}
current.next = newNode;
}
//有些语言不支持++,所以写成+=1
this.length += 1;
}
//2.toString()方法
linkedList.prototype.toString = function() {
var current = this.head;
var listString = '';
while (current) {
listString += current.data + ' ';
current = current.next;
}
return listString;
}
//3.insert()方法
linkedList.prototype.insert = function(position, data) {
//对position进行越界判断
//对链表的长度进行判断
//注意这里是大于length 可以等于length
if (position < 0 || position > this.length) {
return false;
} else {
var newNode = new Node(data);
if (position == 0) {
newNode.next = this.head;
this.head = newNode;
} else {
var index = 0;
var previous = null;
var current = this.head;
while (index++ < position) {
previous = current;
current = current.next;
}
newNode.next = current;
previous.next = newNode;
}
this.length += 1;
return newNode.data;
}
}
//4.get方法
linkedList.prototype.get = function(position) {
//越界判断
if (position < 0 || position >= this.length) {
return null;
}
//获取数据
else {
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
return current.data;
}
}
//5.indexOf()方法
linkedList.prototype.indexOf = function(data) {
var current = this.head;
var index = 0;
while (current) {
if (current.data == data) {
return index;
}
current = current.next;
index += 1;
}
return -1;
}
//6.update()方法
linkedList.prototype.update = function(position, newdata) {
//越界判断
if (position < 0 || position >= this.length) {
return null;
}
//修改数据
else {
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
current.data = newdata;
}
}
//7.removeAt()方法
linkedList.prototype.removeAt = function(position) {
var current = this.head;
//越界判断
if (position < 0 || position >= this.length) {
return null;
} else {
if (position == 0) {
this.head = this.head.next;
} else {
var index = 0;
var previous = null;
while (index++ < position) {
previous = current;
current = current.next;
}
previous.next = current.next;
}
this.length -= 1;
return current.data;
}
}
//8.remove()方法
linkedList.prototype.remove = function(data) {
var position = this.indexOf(data);
return this.removeAt(position);
}
//9.isEmpty()方法
linkedList.prototype.isEmpty = function() {
return this.length == 0;
}
//10.size()方法
linkedList.prototype.size = function() {
return this.length;
}
}
双向链表
双向链表的封装
function DoublyLinkedList() {
this.head = null;
this.tail = null;
this.length = 0;
function Node(data) {
this.data = data;
this.prev = null;
this.next = null;
}
//1.append()方法
DoublyLinkedList.prototype.append = function(data) {
//创建新节点
var newNode = new Node(data);
//判断添加的是否是第一个节点
if (this.length == 0) {
this.head = newNode;
this.tail = newNode;
}
//不是第一个节点
else {
newNode.prev = this.tail;
this.tail.next = newNode;
this.tail = newNode;
}
//有些语言不支持++,所以写成+=1
this.length += 1;
}
//2.toString()方法
DoublyLinkedList.prototype.toString = function() {
return this.backwardString();
}
//3.forwardString() 向前遍历方法
DoublyLinkedList.prototype.forwardString = function() {
var current = this.tail;
var listString = '';
while (current) {
listString += current.data + ' ';
current = current.prev;
}
return listString;
}
//4.backwardString() 向后遍历方法
DoublyLinkedList.prototype.backwardString = function() {
var current = this.head;
var listString = '';
while (current) {
listString += current.data + ' ';
current = current.next;
}
return listString;
}
//5.insert()方法
DoublyLinkedList.prototype.insert = function(position, data) {
//越界判断
if (position < 0 || position > this.length) {
return false;
} else {
//创建新的节点
var newnode = new Node(data)
//判断原来的链表是否为空
if (this.length == 0) {
this.head = newnode;
this.tail = newnode;
} else {
if (position == 0) {
this.head.prev = newnode;
newnode.next = this.head;
this.head = newnode;
} else if (position == this.length) {
newnode.prev = this.tail;
this.tail.next = newnode;
this.tail = newnode;
} else {
var current = this.head;
var index = 0;
//index第一次取0!!!
while (index++ < position) {
current = current.next;
}
//修改指针
newnode.next = current;
newnode.prev = current.prev;
current.prev.next = newnode;
current.prev = newnode;
}
}
}
this.length += 1;
return true;
}
//6.get()方法
DoublyLinkedList.prototype.get = function(position) {
//越界判断
if (position < 0 || position >= this.length) {
return null;
} else {
if (position < this.length / 2) {
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
return current.data;
} else {
var current = this.tail;
var index = this.length - 1;
while (index-- > position) {
current = current.prev;
}
return current.data;
}
}
}
//7.indexOf()方法
DoublyLinkedList.prototype.indexOf = function(data) {
var current = this.head;
var index = 0;
while (current) {
if (current.data == data) {
return index;
} else {
current = current.next;
index += 1;
}
}
return -1;
}
//8.update()方法
DoublyLinkedList.prototype.update = function(position, newdata) {
//越界判断
if (position < 0 || position >= this.length) {
return flase;
} else {
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
current.data = newdata;
return true;
}
}
//9.removeAt()方法
DoublyLinkedList.prototype.removeAt = function(position) {
var current = this.head;
//越界判断
if (position < 0 || position >= this.length) {
return null;
} else {
if (this.length == 1) {
this.head = null;
this.tail = null;
} else {
if (position == 0) {
this.head.next.prev = null;
this.head = current.next;
} else if (position == this.length - 1) {
current = this.tail;
this.tail.prev.next = null;
this.tail = this.tail.prev;
} else {
var index = 0;
while (index++ < position) {
current = current.next;
}
current.prev.next = current.next;
current.next.prev = current.prev;
}
}
}
this.length -= 1;
return current.data;
}
//10.remove()方法
DoublyLinkedList.prototype.remove = function(element) {
var index = this.indexOf(element);
return this.removeAt(index);
}
//11.isEmpty()方法
DoublyLinkedList.prototype.isEmpty = function() {
return this.length == 0;
}
//12.size()方法
DoublyLinkedList.prototype.size = function() {
return this.length;
}
//13.获取链表的第一个元素
DoublyLinkedList.prototype.getHead = function() {
return this.head.data;
}
//14.获取链表的最后一个元素
DoublyLinkedList.prototype.getTail = function() {
return this.tail.data;
}
}