文章目录
参考学习视频
python03-04-01单向链表
一、单向链表介绍
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。像锁链一样,由一节节节点连在一起,组成一条数据链。
1.1 链表节点结构:
1.2 单向链表的结构
1.3 单链表和单向循环链表
- 单链表:每个节点只有一个属性.next,用于存放其后继节点;尾节点的后继为None;若链表为空,则头节点.head为None。
- 单向循环链表:每个节点只有一个属性.next,用于存放其后继节点;由于循环,故尾节点的后继为头节点;若链表为空,则头节点.head为None。
二、操作单链表
2.1 常用方法(自己定义的)
方法 | 作用 |
---|---|
is_empty() | 链表是否为空 |
length() | 链表长度 |
travel() | 遍历整个链表 |
add(item) | 链表头部添加元素 |
append(item) | 链表尾部添加元素 |
insert(pos, item) | 指定位置添加元素 |
remove(item) | 删除节点 |
search(item) | 查找节点是否存在 |
2.2 单向链表的实现
1、单节点类结构
class SingleNode(object):
"""单链表的结点"""
def __init__(self,item):
# item存放数据元素
self.item = item
# next是下一个节点的标识
self.next = None
2、单链表的增删改查
# #
class Node():
"""表节点结构实现 私有属性__next是指向下个节点的指针,__value为此节点的值"""
def __init__(self, value=None, next=None, ):
self._value = value
self._next = next
# 将方法封装
def getValue(self):
return self._value
def getNext(self):
return self._next
def setvalue(self, value):
self._value = value
def setNext(self, next):
self._next = next
class SingleLinkList(object):
"""操作单链表的方法"""
def __init__(self, Node=None):
"""设置一个头节点"""
self.head = Node
def is_empty(self):
"""判断链表是否为空"""
return self.head is None
def add(self, node):
"""向链表头添加输入"""
# 将插入元素实例化
tmp = Node(node)
# 如果链表为空,则让头指针指向实例化的节点
if self.is_empty():
self.head = tmp
else:
# 如果链表不为空,则先将头部节点指向的节点(内存地址),赋值给要插入节点的指针域
# 然后将头部节点指针域指向要插入的节点
tmp.setNext(self.head)
self.head = tmp
def append(self, node):
"""向链表尾添加数据"""
end_Node = Node(node)
cursor = self.head
# 判断列表是否为空,如果为空,则头部插入
if self.is_empty():
self.add(end_Node)
else:
# 如果不为空,
while cursor.getNext() is not None:
cursor = cursor.getNext()
cursor.setNext(end_Node)
def tarver(self):
"""遍历整个链表"""
cur = self.head
while cur is not None:
print(cur.getValue(), end=" ")
cur = cur.getNext()
print() # 换行
def length(self):
"""链表长度"""
cur = self.head
count = 0
while cur is not None:
count += 1
cur = cur.getNext()
return count
def insert(self, index, node):
"""指定位置插入链表"""
tmp = Node(node)
if self.is_empty():
print("链表为空")
return
elif index <= 0:
# 如果在头部直接插入
self.add(node)
elif index > self.length():
# 如果大于链表长度,则在尾部插入
self.append(node)
else:
count = 0
cur = self.head
while count < (index - 1):
count += 1
cur = cur.getNext()
tmp.setNext(cur.getNext())
cur.setNext(tmp)
def remove(self, index):
"""通过索引 删除节点"""
if self.is_empty():
print("链表为空")
return
if index < 0 or index > self.length()-1:
print("索引范围超出链表长度!")
return
# 删除索引为0的元素
elif index == 0:
self.head = self.head.getNext()
else:
cur = 0 # 索引
pre = self.head
while cur < index-1:
cur += 1
pre = pre.getNext()
pre.setNext(pre.getNext().getNext())
def search(self, value):
"""链表查找节点是否存在,并返回True或者False"""
cur = self.head
if self.is_empty():
print("链表为空!")
return
while cur != None:
if cur.getValue() == value:
return True
cur = cur.getNext()
return False
def change(self, index, value):
"""链表内容替换"""
if self.is_empty():
print("链表为空!")
return
if index < 0 or index > self.length()-1:
print("索引范围超出链表长度!")
return
node = self.head
for i in range(self.length()):
if i == index:
node.setvalue(value)
return
node = node.getNext()
if __name__ == '__main__':
obj = SingleLinkList()
obj.add(1)
obj.tarver()
obj.append(2)
obj.append(4)
obj.add(7)
obj.tarver()
obj.insert(3, 5)
obj.tarver()
obj.remove(1)
obj.tarver()
print(obj.search(2))
obj.tarver()
obj.change(2, 55)
obj.tarver()
3、反转单链表
"""
翻转一条单链表
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
"""
class ListNode:
def __init__(self, x, Next=None):
self.val = x
self.next = Next
# 遍历替换法
def ReverseList(head):
if head == None or head.next == None:
return head
last = None # 前置节点
while head:
tmp = head.next # 保存当前节点的下一个节点,不可缺,因为后面更改了当前节点的next指向
head.next = last # 更改当前节点的next为上一个节点
last = head # 将上一个节点移动到当前节点
head = tmp # 当前节点移动到下一个节点
# head.next, last, head = last, head, head.next 可以简写成
return last
if __name__ == '__main__':
# 创建一个1-5的链表
a = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5,)))))
Node = ReverseList(a)
while Node:
print(Node.val)
Node = Node.next
结果:
5
4
3
2
1