
链表的python实现
self.item = item # 存放节点数据self.next = None # 用于指向下一个节点双链表是在链表的基础上,每个节点有两个指针:一个指向前一个节点,一个指向后一个节点。self.item = item # 用于存放节点数据self.prior = None # 指向前一个节点self.next = None # 指向后一个节点。
一、单向链表
链表是由一系列节点组成的元素集合,每个节点包含两部分,数据域item和指向下一个节点的指针next,通过节点之间的相互连接,形成链表。
1、节点定义
class Node:
def __init__(self, item):
self.item = item # 存放节点数据
self.next = None # 用于指向下一个节点
2、创建链表
头插法
往链表的前面插入元素,插入元素的节点链向原来的头结点,让插入的元素成为新的头节点。
def create_linklist_head(li): # li为列表
head = Node(li[0]) # 先让列表中的第一个元素成为头结点
for element in li[1:]: # 往后遍历列表
node = Node(element)
node.next = head
head = node
return head # 返回头结点,用于实现链表打印
尾插法
往链表后面插入元素,原尾节点链向插入元素,插入元素成为新的尾节点。(注意构造时开始要让头结点和尾节点指向同一个位置)
def create_linklist_tail(li): # li为列表
head = Node(li[0]) # 构造头节点
tail = head # 尾节点和头结点指向同一个位置
for element in li[1:]:
node = Node(element)
tail.next = node
tail = node
return head # 返回头结点用于实现链表的打印
3、链表节点的插入
先找到要插入位置的前面的节点(curnode),curnode.next 表示要插入位置的后面的节点,p表示要插入的节点,可以执行操作 :
p.next = curNode.next
curNode.next = p
# 插入元素
def linklist_insert(curNode, node, element): # curNode为插入元素的前一个元素,element为要插入的元素
p = Node(element)
while curNode: # 找到要插入的位置
if curNode.item == node:
# 节点插入执行的操作
p.next = curNode.next
curNode.next = p
return
curNode = curNode.next
raise ValueError("There is no such element")
4、链表节点的删除
首先找到要删除节点的前一个节点(curnode),所以curnode.next 表示要删除的节点,在执行删除操作:curnode.next = curnode.next.next
del p
前一个节点直接跳过删除节点,链向要删除节点的后一个节点。
# 删除元素
def linklist_delete(curnode, node): # curnode为传进去的头结点,node是要删除的节点的元素
while curnode: # 寻找删除节点的位置
p = curnode.next # p为要删除的节点
if curnode.next.item == node:
if curnode.next.next == None: # 如果要删除的节点是尾节点
curnode.next = None
return
else: # 删除的节点为中间节点
# 删除执行的操作
curnode.next = curnode.next.next
del p
return
curnode = curnode.next
5、链表打印
def print_linklist(node): # 输入头结点
while node: # 遍历链表
print(node.item, end=" ")
node = node.next
6、单向链表封装到类
class Node:
def __init__(self, item):
self.item = item
self.next = None
class Linkedlist:
def __init__(self):
self.head = None
self.tail = None
def create_linklist_head(self, item): # 头插法 可以向前插入单个元素
node = Node(item) # 创建Node对象
if not self.head:
self.head = node
self.tail = self.head
else:
node.next = self.head # 将存入的元素指向头元素
self.head = node # 让新存入的元素成为头元素
def linklist_head_insert(self, li): # 使用头插法,批量插入列表数据
if not self.head:
self.head = Node(li[0]) # 创建Node对象,成为头元素
for element in li[1:]: # 遍历从下标1开始的列表,将所有元素存入链表
self.create_linklist_head(element)
else:
for element in li: # 遍历从下标1开始的列表,将所有元素存入链表
self.create_linklist_head(element)
def create_linklist_tail(self, item): # 尾插法 可以插入单个元素
node = Node(item) # 创建Node对象
if not self.head:
self.head = node
self.tail = self.head
else:
self.tail.next = node # 尾链接新元素
self.tail = node # 让新元素成为新的尾
def linklist_tail_insert(self, li): # 使用尾插法,批量插入列表数据
if not self.head:
self.head = Node(li[0]) # 头结点指向列表第一个元素
self.tail = self.head # 刚开始头结点与尾节点一致
# self.tail = Node(li[0])
# 问题:只有self.tail = Node(li[0])时,从head开始遍历链表没有输出,从tail开始遍历链表只会输出第一个元素
# 1:self.tail = Node(li[0])表示创建了一个新的Node对象,难道是因为没有设置头结点的原因吗?
# 2:self.tail = self.head 表示将尾节点设置为与头节点相同的引用
# 我懂了,在这个链表中遍历是向后遍历的,而尾节点指向None,所以只能打印最后一个元素
# 只有self.tail = Node(li[0])时,链表没有指定头元素,所以从head遍历没有输出
for element in li[1:]: # 遍历从下标1开始的列表,将所有元素存入链表
self.create_linklist_tail(element)
else:
for element in li: # 遍历从下标1开始的列表,将所有元素存入链表
self.create_linklist_tail(element)
# 链表节点的插入
def linklist_insert(self, node, data): # node是要插入的位置(在哪个元素后面插入),data是要插入的数据
curnode = self.head # 指向头结点
while curnode: # 循环链表
if curnode.item == node: # 找到位置
# 执行插入元素操作
newnode = Node(data) # 生成Node对象
newnode.next = curnode.next # 插入元素向后指向后一个元素
curnode.next = newnode # 前一个元素向后指向插入的元素
break
else:
curnode = curnode.next # 进入下一个节点
# 链表节点的删除
def linklist_del(self, data):
curnode = self.head
p = None
while curnode:
if curnode.item != data:
p = curnode # p表要删除元素的前一个元素示
curnode = curnode.next
else: # 找到了要删除的元素
p.next = p.next.next # 要删除元素的前一个元素向后指向要删除元素的下一个元素
curnode = curnode.next # 进入下一个节点
del p
# 链表输出
def print_linklist(self):
curnode = self.head
while curnode:
print(curnode.item, end=',')
curnode = curnode.next # 进入下一个节点
ll = Linkedlist()
ll.create_linklist_head(3)
ll.create_linklist_head(9)
ll.print_linklist()
二、双向链表
1、节点定义
双链表是在链表的基础上,每个节点有两个指针:一个指向前一个节点,一个指向后一个节点。
class Node:
def __init__(self, item):
self.item = item # 用于存放节点数据
self.prior = None # 指向前一个节点
self.next = None # 指向后一个节点
2、创建双链表
头插法
在单链表头插法的基础上加一个向前指针,原来头结点的向前指针指向插入节点,插入节点的向后指针指向头结点,再使插入的节点成为新的头结点。
# 头插法
def create_double_linklist_head(li): # li为列表
head = Node(li[0])
tail = head
for element in li[1:]:
node = Node(element)
# 执行插入操作
head.prior = node
node.next = head
head = node
return head # 返回头结点,以便遍历链表
尾插法
同理,在单链表的基础上加一个向前指针,原尾节点的向后指针指向插入节点,插入节点的向前指针指向原尾节点,再让插入元素成为新的尾节点。
# 尾插法
def create_double_linklist_tail(li): # li为要构建链表的列表
head = Node(li[0])
tail = head
for element in li[1:]:
node = Node(element)
# 插入操作
tail.next = node
node.prior = tail
tail = node
return head # 同样返回头节点,以便打印链表
3、链表节点的插入
类比单链表插入,先找到要插入位置的前一个节点(curnode),curnode.next 表示要插入位置的后一个节点,执行操作:p.next = curnode.next
curnode.next.prior = p
p.prior = curnode
curnode.next = p
# 中间节点的插入
def double_linklist_insert(head, node, element): # head是头结点,curnode为插入位置的前一个节点的元素,element为要插入的元素
curnode = head
p = Node(element) # 创建要插入的节点
while curnode:
if curnode.item == node:
p.next = curnode.next
curnode.next.prior = p
p.prior = curnode
curnode.next = p
return
curnode = curnode.next
4、链表节点的删除
同上述先找节点,把要删除节点的前一个节点跳过要删除节点向后指向删除节点的后一个节点,后一个节点同理跳过删除节点指向后一个节点,执行操作:
p = curnode.next
curnode.next = p.next
p.next.prior = curnode
del p
def double_linklist_delete(head, node):
curnode = head
while curnode:
p = curnode.next
if p.item == node:
curnode.next = p.next
p.next.prior = curnode
del p
return
curnode = curnode.next
5、打印链表
def print_double_linklist(node): # 输入头结点
while node: # 遍历链表
print(node.item, end=" ")
node = node.next
6、双链表封装到类
# 建立双链表
class Node:
def __init__(self, item=None):
self.item = item # 元素
self.next = None # 向后指针
self.prior = None # 向前指针
class Doublelinklist:
def __init__(self):
self.head = None
self.tail = None
def create_linklist_head(self, item): # 头插法 可以插入单个元素
node = Node(item) # 把元素存入链表
node.next = self.head # 将存入的元素通过链表向后指针指向头元素
self.head.prior = node
self.head = node # 让新存入的元素成为头元素
def linklist_head_insert(self, li): # 使用头插法,批量插入列表数据
self.head = Node(li[0])
for element in li[1:]: # 遍历从下标1开始的列表,将所有元素存入链表
self.create_linklist_head(element)
def create_linklist_tail(self, item): # 尾插法 可以向后插入单个元素
node = Node(item) # 把元素存入链表
self.tail.next = node # 尾链接新元素
node.prior = self.tail
self.tail = node # 让新元素成为新的尾
def linklist_tail_insert(self, li): # 使用尾插法,批量插入列表数据
self.head = Node(li[0]) # 头结点指向列表第一个元素
self.tail = self.head # 刚开始头结点与尾节点一致
for element in li[1:]: # 遍历从下标1开始的列表,将所有元素存入链表
self.create_linklist_tail(element)
# 链表节点的插入
def linklist_insert(self, node, data): # node是要插入的位置(在哪个元素后面插入),data是要插入的数据
curnode = self.head # 指向头结点
while curnode: # 循环链表
if curnode.item == node: # 找到位置
# 执行插入元素操作
newnode = Node(data)
newnode.next = curnode.next # 插入元素向后指向下一个元素
curnode.next.prior = newnode # 下一个元素向前指向插入的元素
newnode.prior = curnode # 插入元素向前指向前一个元素
curnode.next = newnode # 前一个元素向后指向插入的元素
break
else:
curnode = curnode.next # 进入下一个节点,继续遍历
# 链表节点的删除
def linklist_del(self, data):
curnode = self.head
p = None
while curnode:
if curnode.item != data:
p = curnode # p表要删除元素的前一个元素
curnode = curnode.next
else: # 找到了要删除的元素
delnode = p.next # 表示要删除的元素
p.next = delnode.next # 要删除元素的前一个元素向后指向要删除元素的后一个元素
delnode.next.prior = p # 要删除元素的后一个元素向前指向要删除元素的前一个元素
curnode = curnode.next # 进入下一个节点,继续遍历
del p
def print_linklist(self):
curnode = self.head
while curnode:
print(curnode.item, end=',')
curnode = curnode.next # 进入下一个节点
dll = Doublelinklist()
dll.linklist_tail_insert([1, 3, 2, 5, 4, 7, 6])
# dll.linklist_head_insert([1, 3, 2, 5, 4, 7, 6])
dll.linklist_insert(4, 9)
dll.linklist_del(5)
dll.print_linklist()
更多推荐
所有评论(0)