python双向链表_学习笔记-链表、双向链表的原理和方法

初学数据结构,链表给我的感觉相较于数组栈队列,是更加烧脑的,没搞懂时容易把人搞晕,现在总结下它的基础原理和方法。

简单链表结构

其中链表头像是火车头指向下一个车厢,如果没有车厢则指向null,车厢数据存放数据元素,指针是链接下一节车厢的钩子,通过指针钩子找到下一节车厢,如果没有下一届车厢也指向null。

实现一下简单链表的常见方法

function abc() {

//创建链表对象

function obj (data) {

this.key = data,

this.value = null

}

this.length = 0

this.objs = ''

//向末尾插入

abc.prototype.append = function (data) {

var obj2 = new obj(data)

if(this.objs.length == 0) {

this.objs = obj2

} else {

var parameter = this.objs

while(parameter.value) {

parameter = parameter.value

}

parameter.value = obj2

}

this.length += 1

}

//将链表所有元素打印

abc.prototype.tostring = function () {

var parameter = this.objs

var chr = ''

for (var i=0; i

chr += parameter.key

parameter = parameter.value

}

return chr

}

//向指定位置插入

abc.prototype.insert = function (num, data) {

if(num<0 || num>this.length) return false

var parameter = this.objs

var obj2 = new obj(data)

var index = 0

while(index++ < num-1) {

parameter = parameter.value

}

var parameter2 = parameter.value

parameter.value = obj2

parameter.value.value = parameter2

this.length += 1

}

//将某个位置值更新

abc.prototype.updata = function (num, data) {

if(num>this.length-1) return false

var parameter = this.objs

var parameter = this.objs

for(var i=0; i

parameter = parameter.value

}

parameter.key = data

}

//将特定下标值删除

abc.prototype.removeAt = function (num) {

if(num>this.length-1) return false

if(num==0) {

this.objs = null

this.length = 0

return

}

var parameter = this.objs

for(var i=0; i

parameter = parameter.value

}

parameter.value = null

this.length = this.length - num

}

//将特定属性值删除

abc.prototype.remove = function (obj) {

var parameter = this.objs

for(var i=0; i

if(parameter.key == obj) {

parameter = null

this.length = i

return this.objs

}

parameter = parameter.value

}

return false

}

//返回是否为空

abc.prototype.isEmpty = function () {

return this.objs.length == 0

}

//返回长度

abc.prototype.size = function () {

return this.length

}

//返回指定下标值

abc.prototype.get = function (num) {

if(num > this.length-1) return false

var parameter = this.objs

for(var i=0; i<=num-1; i++) {

parameter = parameter.value

}

console.log(this.objs);

return parameter

}

//判断是否有此值

abc.prototype.indexof = function (data) {

var parameter = this.objs

for(var i=0; i

if(parameter.key == data) {

return i

}

parameter = parameter.value

}

return -1

}

}

var abc2 = new abc()

abc2.append('qwer')

abc2.append('asdf')

abc2.append('zxcv')

abc2.insert(3, 'poiu')

abc2.updata(2, 'qqqq')

// abc2.removeAt(2)

// console.log(abc2.remove('asdf'))

console.log(abc2.indexof('asdf')); //1

console.log(abc2.get(2)) //{key: "qqqq", value: obj}

console.log(abc2.tostring()) //qwerasdfqqqqpoiu

console.log(abc2.isEmpty()); //false

console.log(abc2.objs); //{key: "qwer", value: obj}

总结下方法就是,增删查改,对于容器类的数据结构来说,最重要的事就是增删查改,如何高效优雅的对数据结构进行增删查改就是一个好的算法应该干的事。

除了单向链表,还有双向链表,而双向链表的出现是为了解决单向链表,逆序查找值非常不方便而出现的。

双向链表结构

废话少说,直接进入封装双向链表常见方法阶段。

function abc () {

function node (praevia, data) {

this.praevia = praevia

this.data = data

this.postf = null

}

this.length = 0

//第一个元素

this.objs = {}

//最后一个元素

this.tail = {}

//从链表最后插入一个节点

abc.prototype.append = function (data) {

if(this.length == 0) {

var obj2 = new node(null, data)

this.objs = obj2

} else {

var parameter = this.objs

while(parameter.postf) {

parameter = parameter.postf

}

var obj2 = new node(parameter, data)

parameter.postf = obj2

}

this.length += 1

this.tail = obj2

return this.objs

}

//将链表以字符串形式打印出来

abc.prototype.tostring = function () {

var num = 0

var chr = ''

var parameter = this.objs

while(num++ < this.length) {

chr += parameter.data + ' '

parameter = parameter.postf

}

return chr

}

//将链表以正序形式打印出来

abc.prototype.forwardstring = function () {

return this.tostring()

}

//将链表以倒叙形式打印出来

abc.prototype.backwordstring = function () {

var num = 0

var arr = []

var chr = ''

var parameter = this.objs

while(num++ < this.length) {

arr.push(parameter.data)

parameter = parameter.postf

}

while(num-- > 1) {

chr += arr.pop() + ' '

}

return chr

}

//向列表特定下标插入值

abc.prototype.insert = function (num, data) {

if(num > this.length || num < 0) return false

var index = 0

var parameter = this.objs

if(num == 0) {

var obj2 = new node(null, data)

obj2.postf = this.objs

this.objs.praevia = obj2

this.objs = obj2

this.length += 1

return

}

while(index++ < num-1) {

parameter = parameter.postf

}

var obj2 = new node(parameter, data)

obj2.postf = parameter.postf

parameter.postf = obj2

if(num==this.length) {

this.tail = obj2

}

this.length += 1

}

//获得特定下标处元素

abc.prototype.get = function (num) {

var index = 0

var parameter = this.objs

while(index++ < num) {

parameter = parameter.postf

}

return parameter

}

//修改特定下标的值

abc.prototype.updata = function (num, data) {

var obj2 = this.get(num)

obj2.data = data

}

//删除方法

abc.prototype.delete = function (parameter) {

var head = parameter.praevia

var foot = parameter.postf

parameter.praevia.postf = foot

parameter.postf.praevia = head

this.length -= 1

}

//删除特定下标处的值

abc.prototype.removeAt = function (num) {

if(num<0 || num>this.length-1) return null

var index = 0

var parameter = this.objs

if(num==0) {

parameter = parameter.postf

parameter.praevia = null

this.objs= parameter

this.length -= 1

return this.objs

}

while(index++ < num) {

parameter = parameter.postf

}

if(num==this.length-1) {

var a = parameter.praevia

this.tail = a

}

this.delete(parameter)

}

//删除特定的元素

abc.prototype.remove = function (data) {

var index = 0

var parameter = this.objs

while(index++ < this.length) {

if(parameter.data == data) {

if(index==this.length-1) {

var a = parameter.praevia

this.tail = a

}

this.delete(parameter)

return this.objs

}

parameter = parameter.postf

}

return -1

}

}

var newNode = new abc()

newNode.append('abcd')

newNode.append('asdf')

newNode.append('zxcv')

newNode.insert(2, 'mnbv')

newNode.insert(0, 'dfgh')

newNode.updata(2 , 'liuy')

newNode.removeAt(3)

console.log(newNode.remove('asdfas')) //-1

console.log(newNode.remove('abcd')) //Object

console.log(newNode.tostring()); //dfgh liuy zxcv

console.log(newNode.forwardstring()); //dfgh liuy zxcv

console.log(newNode.backwordstring()); //zxcv liuy dfgh

console.log(newNode.get(3)); //null

console.log(newNode.tail); //Object

和单向链表相比,因为多了一层关系,所以在删除添加时需要多一层操作把上个指针拿到并赋值,搞懂了单层链表就不是很难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值