基本概念
- 链表:顺序表是连续存储,
节点与节点之间靠“链”(地址)链接
,顺序表与链表都叫线性表。 - 链表实现:每个元素有两个连续的内存:结点,结点分为
数据区(elem)
和链接地址(指针)区(next)
- 链表优点:可以不占用连续的内存
- 链表缺点:需要存储下一节点地址,总体占用的内存比顺序表大
- 顺序表与链表最坏时间复杂度对比
单向列表
- 头列表,尾列表
- 面向对象(class)编程,定义列表操作方法及储存
- Python中没有指针类型数据,如何实现地址区数据储存?
通过“=赋值”操作,使一个节点指向下一节点
Python中实现a, b 值交换:a,b = b,a (Tuple 类型),Python中改变的是a,b的对象内存的地址,而不是改变对象内存内的元素
双向列表
- 每个节点中包含3个元素:前面节点的地址,存储元素,后面节点的地址
源代码
- 理解见源代码内备注
class Node:
def __init__(self, elem):
self.elem = elem
self.next = None
self.prev = None
class SingleLinkList: #构建单向列表
def __init__(self, node = None):
self._head = node #_head 是第一个节点,包含第一个元素和下一个节点的地址
def is_empty(self):
return self._head == None
def append(self, item):
node = Node(item) #创建添加的节点
if self._head == None: #判断链表是否为空(用self对象(或者说实例)调用方法is_empty)
self._head = node #如果头节点为空,把新添加的节点作为头节点
else:
cur = self._head #如果头节点不为空,指定头节点为当前节点(**cur为Node类实例**), cur 与self._head 地址一样
# print(cur) #测试一下是否能链接
# print(self._head)
# print(self._head.next)
while cur.next != None: #在节点中的next不为空的情况下(不是最后一个节点)
cur = cur.next #遍历列表,把下一节点地址赋给此几点
# print(cur)
cur.next = node #类的实例化,cur.next也是Node类!cur.next存入node的地址,同时self._head.next 也被赋值!!!
def length(self):
cur = self._head #遍历开始
count = 0
while cur != None:
count += 1
cur = cur.next #遍历
return count
def travel(self):
cur = self._head # 遍历开始
while cur != None:
print(cur.elem,end=",")
cur = cur.next # 遍历
def headadd(self, item):
node = Node(item)
if self.is_empty():
self._head = node
else:
node.next = self._head
self._head = node
def addatpos(self, pos, item):
node = Node(item)
count = 1
cur = self._head
while count != pos:
count += 1
cur = cur.next
node.next = cur.next
cur.next = node
def search(self, item):
cur = self._head
while cur != None:
if cur.elem == item:
return "bingo"
break
cur = cur.next
return "Nogo"
class DoubleLinkList(SingleLinkList): #构建双向列表
def append(self, item):
node = Node(item)
if self._head == None:
self._head = node
else:
cur = self._head
while cur.next != None:
cur = cur.next #遍历列表
cur.next = node #链接下一节点
node.prev = cur
# print(cur.prev) #验证一下地址是不是能衔接上
# print(cur)#验证一下地址是不是能衔接上
# print(cur.next,end="\n\n")#验证一下地址是不是能衔接上
def addatpos(self, pos, item):
node = Node(item)
count = 1
cur = self._head
while count != pos:
count += 1
cur = cur.next
node.next = cur.next
node.prev = cur
cur.next = node
cur.next.prev = node
#-------------------------以下为测试运行---------------------
# sll = SingleLinkList()
# sll.append(1)
# sll.append(2)
# sll.append(1)
# sll.append(4)
# sll.headadd(10000)
# sll.addatpos(1,999999)
# sll.travel()
# print(sll.search(2))
dll = DoubleLinkList()
dll.append(1)
dll.append(2)
dll.append(3)
dll.append(4)
dll.append(5)
dll.append(1322)
dll.addatpos(2, 88888)
print(dll.travel())