PS:代码注释自己理解的&插入排序法和双链表图自己画的,如有错误,请告知谢谢
单链表
顺序表和单链表的比较
单链表采用的是链式存储结构,使用一组地址任意的存储单元来存放数据元素。在单链表中,存储的每一条数据都是以节点来表示的,每个节点的构成为:元素(存储数据的存储单元) + 指针(存储下一个节点的地址值)。
单链表操作:
1)把需要添加进入单链表的数据封装成节点对象 2)判断单链表是否为空表,也就是判断单链表中是否存在节点: a.如果单链表为空表,那么我们就将"添加节点"设置为单链表的首节点和尾节点 b.如果单链表不是空表,那么我们就将"添加节点"放到尾节点的后面,并设置"添加节点"为单链表的尾节 点
1) 通过循环,找到需要被删除的节点 2) 让"删除节点的前一个节点"指向"删除节点的后一个节点"
1) 把需要插入单链表的数据封装成节点对象 2) 通过循环,找到插入节点的位置 3) 让"插入节点位置的前一个节点"指向"需要插入的 节点",然后再让"需要插入的节点"指向"插入位置对应 的节点"
单链表的排序算法(插入排序法)
def sort1(self):
if self._head is None:
return
cur = self._head.next
while cur is not None:
x = cur.item
p = self._head
# p不等于最后一个 且 前面的值小于后面的值 则不需要换位置,直接下移判断下一个值
while p is not cur and p.item <= x:
p = p.next
while p is not cur: # p不等于最后一个的
y=p.item # 把p值赋值给变量y
p.item=x # 把cur值赋值给P值
x=y # 变量y赋值给cur的值
p=p.next # p下移
cur.item=x # 回填最后一个元素
cur=cur.next #至此一个判断流程结束,下移下一个循环
双链表
双链表也叫双向链表,它依旧采用的是链式存储结构。在双链表中,每个节点中都有两个指针, 分别指向直接前驱节点prev(保存前一个节点的地址值)和直接后继节点next(保存后一个节点的地址值)。
# 定义一个结点类Node。初始化item存放数据元素,next下一节点,prev上一节点。
class Node(object):
def __init__(self,item):
self.item=item
self.next=None
self.prev=None
# 定义一个类BilateralLinkList进行双向链表的操作
class BilateralLinkList(object):
def __init__(self):
self._head=None
"""判断链表是否为空is_empty"""
# 直接return
def is_empty(self):
return self._head is None
"""链表长度length"""
# (指针指向None 表示到达尾部)游标cur指向head,循环初始次数0,循环遍历:当cur不是None则循环次数+1,指针下移,循环外返回count
def length(self):
cur=self._head
count=0
while cur is not None:
count+=1
cur=cur.next
return count
"""遍历链表items"""
# 游标cur指向头结点,循环遍历:当游标cur不是None则返回生成器指针的值,指针下移
def items(self):
cur=self._head
while cur is not None:
yield cur.item
cur=cur.next
"""向链表头部添加元素add"""
# 添加新节点,判断is_empty(),存在:头部结点指针修改为新结点,否:新结点指针指向原头部结点,原头部 prev 指向 新结点,head 指向新结点
def add(self,item):
node=Node(item)
if self.is_empty():
self._head=node
else:
node.next=self._head
self._head.prev=node
self._head=node
"""尾部添加元素append"""
# 添加新节点,判断是否为空,是:头部结点指针修改为新结点,否(移动到尾部):游标指向头结点,循环遍历游标下一个不为空:游标修改为下一个,循环外新结点上一级指针指向旧尾部cur,旧尾部指向新结点
def append(self,item):
node=Node(item)
if self.is_empty():
self._head=node
else:
cur=self._head
while cur.next is not None:
cur=cur.next
node.prev=cur
cur.next=node
""" 指定位置插入元素insert"""
# 判断如果下标小于等于0就头部添加数据元素item,如果下标大于本身长度减一就尾部添加数据元素,否则添加新节点、游标指向头结点,循环下标,游标指向下一节点,循环外新节点的向下指针指向当前节点,新节点的向上指针指向当前结点的上一结点,当前上一结点的向下指针指向新节点,当前结点的向上指针指向新节点
def insert(self,item,index):
if index<=0:
self.add(item)
elif index>self.length()-1:
self.append(item)
else:
node=Node(item)
cur=self._head
for i in range(index):
cur=cur.next
node.next=cur
node.prev=cur.prev
cur.prev.next=node
cur.prev=node
""" 删除结点 remove"""
# 判断如果是空的链表直接返回;游标指向头结点;【有下面三种情况:头,中间,尾巴】
# 删除元素在第一个【循环遍历当游标的下一个不是空:(如果游标的数据元素等于数据元素:游标的上一个结点的下一个结点等于指向游标的下一个结点,游标的下一个结点的上一个结点指向游标的上一个结点,返回TRUE。判断外:游标指向游标的下一节点)】
# 删除元素在最后一个(如果游标的数据元素等于数据元素,游标的上一个结点的下一个节点指向空,返回TRUE。)
def remove(self,item):
if self.is_empty():
return
cur=self._head
if cur.item==item:
if cur.next is None:
self._head=None
return True
else:
self._head=cur.next
cur.next.prev=None
return True
while cur.next is not None:
if cur.item==item:
cur.prev.next=cur.next
cur.next.prev=cur.prev
return True
cur=cur.next
if cur.item==item:
cur.prev.next=None
return True
"""查找元素是否存在find"""
# 返回(数据元素在自身的数据元素)
def find(self,item):
return item in self.items()
"""搜索某个元素的key,search"""
# 查找指定元素,在函数中传入一个链表对象和值,然后用这个值去判断链表内每一个元素的值,符合就返回。
# 定义双向链表头节点对象的变量x,循环的条件则是头结点对象不是None,也就是传进来的这个链表必须是存在且有值的。另一个条件则是这个节点的值不等于需要去匹配的元素值,否则会直接退出。循环外就直接返回该节点。
def search(self,k):
x=self._head
while x!=None and x!=k:
x=x.next
return x
环形链表
(1) 环形单链表
(2) 环形双链表
代码来源:
《数据结构Python page97》, 算法设计与分析——链表_von Neumann的博客-CSDN博客