文章目录
- 一、什么是双链表?
- 二、双向链表的特点
- 三、 双向链表的封装
- 四、双链表常见的操作(增删改查)
- 4.1 append(element):向链表尾部添加一个新的项
- 4.2 insert(position,element):向链表的特定位置插入一个新的项
- 4.3 get(position):获取对应位置的元素
- 4.4 indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1
- 4.5 updata(position,element):更新某个元素
- 4.6 removeAt(position):从链表的特定位置移除一项(根据位置)
- 4.7 remove(element);从链表移除一项 (根据元素)
- 3.8 isEmpty():判空
- 3.9 size():返回链表包含的元素个数。
- 3.10 tostring():输出
- 五.源码
一、什么是双链表?
双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
二、双向链表的特点
- 可以使用head和一个tail分别指向头部和尾部的节点
- 每个节点都由三部分组成:前一个节点的指针,后一个节点的指针,元素
- 双向链表的第一个节点prev是null
- 双向链表的最后的节点next是null;
三、 双向链表的封装
function DoublyLinkedList() {
// Node节点
function Node(data) {
this.prev=null;
this.item=data;
this.next=null;
}
// 属性
this.head=null;//头节点
this.tail=null;//尾节点
this.length=0;//长度
}
四、双链表常见的操作(增删改查)
- append(element):向链表尾部添加一个新的项
- insert(position,element):向链表的特定位置插入一个新的项
- get(position):获取对应位置的元素
- indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1
- updata(position,element):更新某个元素
- removeAt(position):从链表的特定位置移除一项(根据位置)
- remove(element);从链表移除一项(根据元素)
- isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false。
- size():返回链表包含的元素个数。
- tostring():输出
- forwardString():返回正向遍历的节点字符串形式
- backworkString():返回正向遍历的节点字符串形式
4.1 append(element):向链表尾部添加一个新的项
步骤:
1.创建新的节点(newNode)
2.判断是否添加的是第一个节点
3.若是:如图1
4.不是:如图2
5.length++
图1:
图2:
DoublyLinkedList.prototype.append=function(data){
// 1.根据data创建节点
var newNode=new Node(data);
// 2.判断添加的是否为第一个节点
if (this.length==0) {
this.head=newNode;
newNode.prev=null;
this.tail=newNode;
} else {
this.tail.next=newNode;
newNode.prev=this.tail;
this.tail=newNode;
}
// 3.length++
this.length+=1;
}
4.2 insert(position,element):向链表的特定位置插入一个新的项
步骤:
1.越界判断
2.创建新的节点
3.判断此时链表是否为空
3.1 空:与head。tail连接
3.2 不为空
3.3.1 position=0
3.3.2 position=length
3.3.3 postion在中间
DoublyLinkedList.prototype.insert = function (position, data) {
// 1.越界判断
if (position < 0 || position > this.length) {
return false;
}
// 2.创建新的节点
var newNode = new Node(data);
// 3.判断此时链表是否为空
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;
var previous=null;
while (index<position) {
previous=current;
current=current.next;
index+=1;
}
//**
newNode.prev=previous;
previous.next=newNode;
newNode.next=current;
current.prev=newNode;
}
}
length+=1;
return true;
}
4.3 get(position):获取对应位置的元素
步骤:
1.position越界判断
2.遍历get元素data
DoublyLinkedList.prototype.get = function (position) {
// 1.position越界判断
if (position < 0 || position >= this.length) {
return null;
}
// 2.遍历get元素data
var current = this.head;
var index=0;
while (index<position) {
current = current.next;
index+=1;
}
return current.data;
}
4.4 indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1
步骤:
遍历求值
DoublyLinkedList.prototype.indexOf=function(element){
// 遍历求值
var current=this.head;
var index=0;
while (current) {
if (current.data==element) {
return index;
}
current=current.next;
index+=1;
}
return -1;
}
4.5 updata(position,element):更新某个元素
步骤:
1.position边界值
2.遍历找到position值并替换
DoublyLinkedList.prototype.updata = function (position,element) {
//1.position边界值
if (position<0||position>=this.length) {
return false;
}
//2.遍历找到position值并替换
var current=this.head;
var index=0;
while (index++<position) {
current=current.next;
}
current.data=element;
return true;
}
4.6 removeAt(position):从链表的特定位置移除一项(根据位置)
步骤:
判断越界
1、判断链表长度是否为1
2、若无为1则处理
3、不为1则:position=0
3.1、position=0
3.2、position=middle
3.3、position=this.length-1
4.length–
DoublyLinkedList.prototype.removeAt = function (position) {
// 越界
if (position < 0 || position >= this.length) {
return false;
}
//1、判断链表长度是否为1
if (this.length == 1) {
this.head = null;
this.tail = null;
} else {
//3、不为1则
//3.1、position=0
if (position == 0) {
this.head = this.head.next;
this.head.prev = null;
//3.3、position=this.length-1
} else if (position == this.length - 1) {
console.log('执行');
this.tail = this.tail.prev;
this.tail.next = null;
//3.2、position=middle
} else {
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
current.prev.next = current.next;
current.next.prev = current.prev;
}
}
//4.length--
this.length -= 1;
return true;
}
4.7 remove(element);从链表移除一项 (根据元素)
步骤
this.removeAt(this.indexOf(element))
DoublyLinkedList.prototype.remove=function(element){
return this.removeAt(this.indexOf(element));
}
3.8 isEmpty():判空
DoublyLinkedList.prototype.isEmpty=function(){
return this.length==0
}
3.9 size():返回链表包含的元素个数。
DoublyLinkedList.prototype.size=function(){
return this.length;
}
3.10 tostring():输出
1.定义变量;
2.依次向后遍历,获取节点
3.返回str
DoublyLinkedList.prototype.tostring=function(){
// 1.定义变量;
// 2.依次向后遍历,获取节点
// 3.返回str
var current=this.head;
var str=''
while (current) {
str+=current.data+' '
current=current.next;
}
五.源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
function DoublyLinkedList() {
// Node节点
function Node(data) {
this.prev = null;
this.data = data;
this.next = null;
}
// 属性
this.head = null;//头节点
this.tail = null;//尾节点
this.length = 0;//长度
/* append(element):向链表尾部添加一个新的项 */
DoublyLinkedList.prototype.append = function (data) {
// 1.根据data创建节点
var newNode = new Node(data);
// 2.判断添加的是否为第一个节点
if (this.length == 0) {
this.head = newNode;
newNode.prev = null;
this.tail = newNode;
} else {
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
// 3.length++
this.length += 1;
}
/* insert(position,element):向链表的特定位置插入一个新的项*/
DoublyLinkedList.prototype.insert = function (position, data) {
// 1.越界判断
if (position < 0 || position > this.length) {
return false;
}
// 2.创建新的节点
var newNode = new Node(data);
// 3.判断此时链表是否为空
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;
while (index < position) {
current = current.next;
index += 1;
}
current.prev.next = newNode;
newNode.prev = current.prev;
newNode.next = current;
current.prev = newNode;
}
}
this.length += 1;
return true;
}
/*get(position):获取对应位置的元素 */
DoublyLinkedList.prototype.get = function (position) {
// 1.position越界判断
if (position < 0 || position >= this.length) {
return null;
}
// 2.遍历get元素data
var current = this.head;
var index = 0;
while (index < position) {
current = current.next;
index += 1;
}
return current.data;
}
/* indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1 */
DoublyLinkedList.prototype.indexOf = function (element) {
// 遍历求值
var current = this.head;
var index = 0;
while (current) {
if (current.data == element) {
return index;
}
current = current.next;
index += 1;
}
return -1;
}
/*updata(position,element):更新某个元素*/
DoublyLinkedList.prototype.updata = function (position, element) {
//1.position边界值
if (position < 0 || position >= this.length) {
return false;
}
//2.遍历找到position值并替换
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
current.data = element;
return true;
}
/* removeAt(position):从链表的特定位置移除一项(根据位置) */
DoublyLinkedList.prototype.removeAt = function (position) {
// 越界
if (position < 0 || position >= this.length) {
return false;
}
//1、判断链表长度是否为1
if (this.length == 1) {
this.head = null;
this.tail = null;
} else {
//3、不为1则
//3.1、position=0
if (position == 0) {
this.head = this.head.next;
this.head.prev = null;
//3.3、position=this.length-1
} else if (position == this.length - 1) {
console.log('执行');
this.tail = this.tail.prev;
this.tail.next = null;
//3.2、position=middle
} else {
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
current.prev.next = current.next;
current.next.prev = current.prev;
}
}
//4.length--
this.length -= 1;
return true;
}
/* remove(element);从链表移除一项(根据元素) */
DoublyLinkedList.prototype.remove=function(element){
return this.removeAt(this.indexOf(element));
}
/* isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false。 */
DoublyLinkedList.prototype.isEmpty=function(){
return this.length==0
}
/* size():返回链表包含的元素个数。 */
DoublyLinkedList.prototype.size=function(){
return this.length;
}
/* tostring():输出 */
DoublyLinkedList.prototype.tostring = function () {
// 1.定义变量;
// 2.依次向后遍历,获取节点
// 3.返回str
var current = this.head;
var str = ''
while (current) {
str += current.data + ' '
current = current.next;
}
return str;
}
/* forwardString():返回正向遍历的节点字符串形式 */
DoublyLinkedList.prototype.forwardString = function () {
var current = this.head;
var str = ''
while (current) {
str += current.data + ' '
current = current.next;
}
return str;
}
/* backworkString():返回正向遍历的节点字符串形式 */
DoublyLinkedList.prototype.backworkString = function () {
var current = this.tail;
var str = ''
while (current) {
str += current.data + ' '
current = current.prev;
}
return str;
}
}
var list = new DoublyLinkedList();
list.append('mmm');
list.append('nnn');
list.append('ccc');
list.append('cba');
list.append('nba');
list.append('bbb');
console.log(list.size());
</script>
</html>