python双循环链表_B03-数据结构-线性结构-线性表循环链表&双向链表&双向循环链表...

数据结构-线性结构-线性表循环链表&双向链表&双向循环链表

文章目录

数据结构-线性结构-线性表循环链表&双向链表&双向循环链表一、循环链表1.1、定义1.2、结构示例1.3、使用说明

二、双向链表2.1、定义2.2、结构示例2.3、使用2.3.1、构建初始化2.3.2、插入操作步骤2.3.3、删除操作步骤

2.4、Python代码实现

三、双向循环链表3.1、定义3.2、结构示例

一、循环链表

1.1、定义

循环链表(circular linked list)是另一种形式的链式存储结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。 由此从表中任一结点出发均可以找到表中其它结点。

1.2、结构示例

1.3、使用说明

循环链表的操作和线性表基本一致,差异在:

循环条件不再是cur.next 为 None,而是 cur.next 是否等于头结点(cur.next == head)

二、双向链表

2.1、定义

双向链表(double linked list):其结点有两个指针域,其一指向直接后继,另一指向直接前趋。

对比单链表,如果我们知道一个结点了。我们可以快速找到它前后的节点。不需要像单链表那样重新从头遍历

2.2、结构示例

2.3、使用

2.3.1、构建初始化

与单链表类似,

2.3.2、插入操作步骤

第一步:cur 指向需要插入位置的前一个节点元素,并创建新要插入的节点

第二步:新要插入的节点的prior指向cur(即a[1]),next指向cur.next(即a[2])

第三步:cur.next.prior(即a[2]的prior)指向新要传入的节点

第四步:cur.next(即a[1]的next)指向新添加的节点

2.3.3、删除操作步骤

第一步:cur指向要删除的元素

第二步:cur.next.prior(即a[3]的prior指针)指向 cur.prior(即a[1])

第三步:cur.prior.next(即a[1]的next指针)指向 cur.next(即a[3])

第四步:处理cur的prior和next 为 None

2.4、Python代码实现

class Node:

def __init__(self, data):

# 链表节点数据域

self.data = data

# 链表节点指针域

self.next = None        # 指向下一个节点

self.prior = None       # 指向上一个节点

class DoubleLinkedList:

"""

双向列表

"""

def __init__(self, li):

self.head = None  # 单链表头

self.length = len(li)  # 单链表长度,节点个数

self.create_list_tail(li)

pass

def create_list_head(self, li):

"""

通过头插入创建单链表

:param li: 对应链表数据,比如['ZHAO', 'QIAN', 'SUN', 'LI', 'ZHOU', 'WU', 'ZHENG', 'WANG']

:return:

"""

# 链表头指向第一个节点

self.head = Node(li[0])

for data in li[1:]:

# 创建新的节点

node = Node(data)

# 新节点next指向,之前头节点指向的节点

node.next = self.head

# 之前节点的 prior 指向新增的节点

self.head.prior = node

# 链表头指向新的节点

self.head = node

def create_list_tail(self, li):

"""

通过尾插法创建单链表

:param li: 对应链表数据,比如['ZHAO', 'QIAN', 'SUN', 'LI', 'ZHOU', 'WU', 'ZHENG', 'WANG']

:return:

"""

# 链表头指向第一个节点

self.head = Node(li[0])

# 链表尾指向第一个节点

tail = self.head

for data in li[1:]:

# 创建新的节点

node = Node(data)

# 当前节点的next指向下一个节点

tail.next = node

# 新增节点的prior指向前一个节点

node.prior = tail

# 链表尾指向新创建的节点

tail = node

def search_ele(self, ele_data):

"""

在静态单链线性表中,查找第一个值为ele_data的元素

若找到返回对应节点下标,否则返回-1

:param ele_data: 元素的值

:return: i 代表匹配的当前元素在链表中的下标

"""

i = 0

cur = self.head

while cur.next:

if cur.data == ele_data:

return i

else:

cur = cur.next

i += 1

else:

return -1

def visit_ele(self, index):

"""

在静态单链线性表中,通过下标访问元素

:param index: 链表下标

:return: 返回对应元素, 若下标不在链表长度范围内,返回None

"""

if type(index) is int and 0 <= index <= self.length:

i = 0

cur = self.head

while i < index:

cur = cur.next

i += 1

else:

return cur

else:

return None

def traverse_ele(self):

"""

在静态单链表线性表中,遍历整个链表

:return: 返回整个链表

"""

i = 0

cur = self.head

while cur.next:

print('%s(%s)' % (cur.data, i), end=' ')

cur = cur.next

i += 1

def insert_ele(self, index, ele_data):

"""

根据下标插入元素

:param index: 插入元素的位置

:param ele_data: 插入的元素

:return:

"""

if type(index) is int and 0 <= index <= self.length:

# 创建需要插入的元素节点

node = Node(ele_data)

i = 0

cur = self.head

# 第一步:从头开始遍历元素,根据index查找对应位置的前一个节点,即cur的位置

while i < index - 1:

cur = cur.next

i += 1

else:

# 第二步:新元素节点的next、prior指向

node.next = cur.next

node.prior = cur

# 第三步:后一个节点prior指向新节点

cur.next.prior = node

# 第四步:cur的next指向新增节点

cur.next = node

self.length += 1

return True

else:

return print('下标异常')

def delete_ele(self, index):

"""

根据下标删除元素

:param index: 需要删除元素的下标

:return:

"""

if type(index) is int and 0 <= index <= self.length:

i = 0

cur = self.head

# 第一步:从头开始遍历元素,根据index查找对应删除位置,即cur的位置

while i < index:

cur = cur.next

i += 1

else:

# 第二步:删除节点的下一节点prior指向删除节点的前一个节点 cur.next.prior(即a[3]的prior指针)指向 cur.prior(即a[1])

cur.next.prior = cur.prior

# 第三步: cur.prior.next(即a[1]的next指针)指向 cur.next(即a[3])

cur.prior.next = cur.next

# 第二步:清理删除节点的prior,next指向None

cur.next = None

cur.prior = None

# 第四步

self.length -= 1

return True

else:

return print('下标异常')

if __name__ == '__main__':

# 创建链表

l1 = DoubleLinkedList(['ZHAO', 'QIAN', 'SUN', 'LI', 'ZHOU', 'WU', 'ZHENG', 'WANG'])

# 查找元素‘SUN'对应的位置

print(l1.search_ele('SUN'))

# 查找下标为3的对应元素值

print(l1.visit_ele(3).data)

# 查找下标为3所有的元素

ele_3 = l1.visit_ele(3)

print(ele_3.prior.data, ele_3.prior.prior.data, ele_3.prior.prior.prior.data)

# 遍历整个链表

l1.traverse_ele()

print('')

# 链表添加某个元素

l1.insert_ele(2, 'NEW')

l1.traverse_ele()

print('')

# 链表删除某个元素

l1.delete_ele(2)

l1.traverse_ele()

三、双向循环链表

3.1、定义

和单链表的循环表类似,双向链表也可以有循环表

3.2、结构示例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值