【数据结构】链表的python实现
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表中的元素可以存在内存中的任何位置。单向链表的节点包含该节点的元素值和下一个节点的地址,双向链表的节点包括该节点的元素值、上一个节点的地址和下一个节点的地址。
一、单向链表的python实现
class LNode(object):
#结点初始化函数, self.val是当前节点的数据,self.next是下一个节点的地址
#为了方便传参, 设置self.next的默认值为None
def __init__(self,val):
self.val = val #节点数据
self.next = None #下一个节点的地址
class LinkList(object):
#初始化head
def __init__(self):
self.head = None
#初始化链表,将data(list)中的数据变为链表的数据结构
def initList(self,data):
#创建头结点
self.head = LNode(data[0])
p = self.head
#为data中的数据构造节点,并加入链表中
for i in data[1:]:
node = LNode(i)
p.next = node
p = p.next
#判断链表是否为空
def isEmpty(self):
if self.head == None:
print('LinkList is Empty')
return True
else:
return False
#获取链表长度
def getLength(self):
#如果链表为空,返回长度为0
if self.isEmpty():
return 0
#如果链表不为空,计算链表长度
else:
p = self.head
length = 0
while p:
length += 1
p = p.next
return length
#遍历链表
def trave(self):
value = []
if self.isEmpty():
print('链表为空链表')
return False
else:
p = self.head
while p:
print(p.val)
value.append(p.val)
p = p.next
return value
#链表插入数据
def insert(self,index,key):
'''
input:index(int):插入位置
key:插入位置的数据
'''
if self.isEmpty():
print('链表为空,无法执行插入操作')
return False
if index < 0 or index > self.getLength() - 1:
print('插入位置超出链表范围')
return False
else:
p = self.head
i = 0
while i <= index:
pre = p
p = p.next
i += 1
node = LNode(key)
pre.next = node
node.next = p
# 删除链表某位置的节点
def delete(self,index):
'''
input:index(int):需要删除节点的位置
'''
if self.isEmpty():
print('链表为空,无法进行删除操作')
return False
if index < 0 or index > self.getLength() - 1:
print('删除节点的位置超出链表范围')
return False
else:
i = 0
p = self.head
while p.next:
pre = p
p = p.next
i += 1
if i == index:
pre.next = p.next
p.next = None
return True
#如果到最后一个节点,删除最后一个节点
pre.next = None
if __name__ == '__main__':
data = [1,2,3,4,5,6]
L = LinkList()
L.initList(data)
print(L.delete(3))
print(L.getLength())
print(L.head.next.val)
L.trave()
二、双向链表的python实现
class LNode(object):
#结点初始化函数, self.val是当前节点的数据,self.next是下一个节点的地址,self.pre是上一个节点的地址
#为了方便传参, 设置self.next和self.pre的默认值为None
def __init__(self,val):
self.val = val #节点数据
self.pre = None #下一个节点的地址
self.next = None #上一个节点的地址
class DLinklist(object):
#初始化head节点
def __init__(self):
self.head = None
#初始化链表,将data(list)中的数据变为链表的数据结构
def initDLink(self,data):
self.head = LNode(data[0])
p = self.head
for i in data[1:]:
node = LNode(i)
p.next = node
node.pre = p
p = p.next
#判断链表是否为空
def isEmpty(self):
if self.head == None:
print('LinkList is Empty')
return True
else:
return False
#获取链表长度
def getLength(self):
#判断链表是否为空
if self.isEmpty():
print('链表为空链表')
return False
else:
p = self.head
length = 0
while p:
length += 1
p = p.next
return length
#遍历链表
def trave(self):
value = []
#判断链表是否为空链表
if self.isEmpty():
print('链表为空链表')
return False
else:
p = self.head
while p:
value.append(p.val)
p = p.next
return value
#在链表尾部插入节点
def push(self,key):
'''
input:key:需要插入链表尾部的节点数值
'''
#如果是空链表,将LNode(key)作为head
if self.head == None:
self.head = LNode(key)
#如果不是空链表,将LNode(key)插入到链表尾部
else:
p = self.head
while p:
p1 = p
p = p.next
node = LNode(key)
p1.next = node
node.pre = p1
#删除链表尾部的节点
def pop(self):
#如果链表为空,无法执行pop操作
if self.isEmpty():
print('链表为空,无法执行pop操作')
return False
#如果链表长度为1时
if self.getLength() == 1:
self.head = None
else:
p = self.head
while p:
p1 = p
p = p.next
p2 = p1.pre
p2.next = None
p1.pre = None
#链表插入数据
def insert(self,index,key):
'''
input:index(int):插入位置
key:插入位置的数据
'''
if self.isEmpty():
print('链表为空,无法执行插入操作')
return False
if index < 0 or index > self.getLength() - 1:
print('插入位置超出链表范围')
return False
#插入位置为0时
if index == 0:
p = self.head
node = LNode(key)
self.head = node
self.head.next = p
p.pre = self.head
else:
p = self.head
i = 0
while i < index:
p1 = p
p = p.next
i += 1
node = LNode(key)
p1.next = node
node.pre = p1
node.next = p
p.pre = node
#删除链表某位置的节点
def delete(self,index):
'''
input:index(int):需要删除节点的位置
'''
if self.isEmpty():
print('链表为空,无法进行删除操作')
return False
if index < 0 or index > self.getLength() - 1:
print('删除节点的位置超出链表范围')
return False
#删除位置为0时
if index == 0:
self.head = self.head.next
else:
p = self.head
i = 0
while i < index:
p1 = p
p = p.next
i += 1
p1.next = p.next
p.next.pre = p1
if __name__ == '__main__':
data = [1]
DL = DLinklist()
DL.initDLink(data)
print(DL.pop())