双向链表 --python描述

概念准备

前驱节点:某个节点之前的那个节点
后继节点:某个节点之后的那个节点
双向链表的第一个结点,是没有前驱节点的,指向None
双向链表的最后一个节点,是没有后继节点的,指向None
每个节点有三个区域:prev区域保存前驱节点的地址指向前驱节点,elem区域保存数据item,next区域指向后继节点保存后继节点地址

继承

双向链表的判空is_empty,长度length,遍历travel,搜索search的实现方式和单链表一样
用面向对象的思想,继承自单链表类
详见链接: 单链表 – python描述.

双向链表代码

#导入单链表类
from 单链表类的模块 import SingleLinkList

class Node(object):
	'''结点类'''
	def __init__(self,item):	#item为传进来的数据,即elem区
		#结点的pre区域(存放前一个结点的地址)
		self.prev = None
		#结点的数据区域
		self.elem = item
		#结点的next区域(存放后一个结点的地址)
		self.next = None

#继承自单链表类,is_empty(),length(),travle(),search()方法直接无需重写
class DoubleLinkList(object):
	'''双向链表类'''
	#双向链表指向
	def add(self,item):
		'''链表头部添加元素,头插法'''
		#创建一个新结点
		node = Node(item)
		#第一步:将新节点的next区域指向第一个结点
		node.next = self.__head
		#第二步:将头结点指向新节点
		self.__head = node
		#第三步:将第一个结点的prev区域指向新节点
		node.next.prev  = node

	def append(self,item):
		'''链表尾部添加元素,尾插法'''
		node = Node(item):
		#如果链表是空链表
		if self.is_empty():
			self.__head = node
		else:
			cur = self.__head	#创建一个游标
			while cur.next != None:	#游标走到最后一个节点时停止,最后一个节点的cur.next 指向 None
				cur = cur.next
			#游标走到最后一个节点,将最后一个节点的next指向新节点,新节点的prev区域指向cur
			cur.next == node
			node.prev == cur
		
	def insert(self,pos,item):
		'''指定位置添加元素
		:param pos 从0开始
		'''
		if pos <= 0:	#当用户输入的位置<0时,默认为头插法
			self.add(item)
		elif pos > (self.length()-1):	#当用户输入的pos大于最大索引时,默认为尾插法
			self.append(item)		
		else:
			#创建游标记录位置
			cur = self.__head
			count = 0
			while count < pos:	#让cur走到要插入的位置
				count += 1
				cur = cur.next
			#然后插入新节点
			node = Node(item)
			#将新节点的next指向cur走到的节点
			Node.next = cur
			#将新节点的prev指向cur指向的节点的前一个节点
			Node.prev = cur.prev
			#将cur指向的节点的prev指向新节点
			cur.prev = node
			#将cur指向的节点的原前驱节点(现已断开被node新节点指着)的next指向新节点
			node.prev.next = node
	
	def remove(self):
		cur = self.__head
		while cur != None:	#指针从第一个节点走到最后一个节点
			#当cur.elem等于用户输入的值时删除
			if cur.elem == item:
				#如果要删除的节点是第一个节点
				if cur == self.__head:
					#将头结点指向第一个节点的后继节点
					self.__head = cur.next
					#如果删了第一个节点后还有节点(该链表不止有一个节点)
					if cur.next:
						#将第一个节点的后继节点的prev区域指向None
						cur.next.prev = None
						
				#如果要删除的是中间节点或最后一个节点		
				else:
					#将cur指向的节点的前驱节点的next区域指向后继节点
					cur.prev.next = cur.next
					#因为最后一个节点时cur.next指向None,不存在cur.net.prev
					if cur.next:
						#将cur指向的节点的后继节点的prev指向前驱节点
						cur.next.prev = cur.prev
					break #删除节点后推出循环
				#当cur.elem不等于item时,继续前行
				else:
					cur = cur.next

if __name__ == '__main__':
	ll = DoubleLinkList()
	print(ll.is_empty())
	print(ll.length())

	ll.append(1)
	print(ll.is_empty())
	pritn(ll.length())

	ll.append(2)
	ll.add(8)
	ll.append(3)
	ll.append(4)
	ll.insert(-1,9)
	ll.travle()
	ll.remove(100)
	ll.travle()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值