数据结构+python(二):链表

数据结构基础+python实现(二):链表

1. 单链表

在这里插入图片描述
由于python语言不具有链表数据结构,所以我们需要定义链表节点和链表类。

1.1 单链表结点的实现:

class Node(object):
		"""节点"""
		def __init__(self,elem):
				self.elem = elem
				self.next = None

1.2 单链表的实现:

class SingleLinkList(object):
		"""单链表"""
		def __init__(self, node = None):
				self.__head = node #头结点设置成私有属性,因为外部使用人员不需要知道头结点的属性
		def is_empty(self):
				"""链表判空"""
				pass
		def length(self):
				"""求链表长度”“”
				pass
		def travel(self):
				"""遍历整个链表"""
				pass
		def add(self, item):
				"""链表头部添加元素"""
				pass
		def append(self, item):
				"""链表尾插"""
				pass
		def insert(self, pos, item):
				"""指定位置添加元素"""
				pass
		def remove(self, item):
				"""删除结点"""
				pass
		def search(self, item):
				"""查找结点是否存在"""
				pass
		
		

定义了一个单链表,实现了基本方法。下面完成方法的具体实现:

def is_empty(self):
		"""链表判空"""
		return self.__head == None
def length(self):
		"""求链表长度“”“
		#cur游标,用来移动遍历结点
		cur = self.__head
		#count记录数量
		count = 0
		while cur != None:
				count +=1
				cur = cur.next
		return count
def travel(self):
		"""遍历整个链表"""
		cur = self.__head
		while cur != None:
				print(cur.elem)
				cur = cur.next
def append(self, item):
		"""链表尾插"""
		node = Node(item)  #定义要插入的结点对象
		if self.is_empty():
			self.__head = node   #判断特殊情况,链表为空
		else:
			cur = self.__head
			while cur.next != None:
				cur = cur.next
			cur.next = node 
				
def add(self, item):
		"""链表头插"""
		node = Node(item)
		node.next = self.__head
		self.__head = node 
def insert(self, pos, item):
		"""在指定位置插入元素
		:param	pos	从0开始
		"""
		if pos <= 0 :
			self.add(item)   #如果插入位置小于0,按头插法
		elif pos > (self.length()-1):
			self.append(item)   #如果插入位置大于链表长度,按尾插法
		else:
			pre = self.__head
			count = 0
			while count < (pos-1):
				count += 1
				pre = pre.next
			# 当循环退出后,pre指向pos-1位置
			node = Node(item)
			node.next = pre.next
			pre.next = node 
def search(self, item):
		"""查找结点是否存在"""
		cur = self.__head
		while cur !=None:
			if cur.elem = item:
				return ture
			else:
				cur = cur.next
		return False
def remove(self, item):
		"""删除结点"""
		cur = self.__head
		pre = None   #cur已经指向第一个结点了,pre指向空,和cur之间保持一个距离
		while cur != None:
			if cur.elem == item:
				# 先判断此结点是否是头结点,如果是头结点的话,pre.next错误(因为开始pre指向空),所以需要self.__head指向cur.next
				# 头结点
				if cur == self.__head:
					self.__head = cur.next
				else:
					pre.next = cur.next
				break
			else:
			#   移动过程有先后顺序,保持同步
				pre = cur
				cur = cur.next
#  这时候需要定义两个游标!

2. 双向链表
在这里插入图片描述
2.1 双向链表结点的实现:

class Node(object):
	"""结点"""
	def __init__(self, item):
		self.elem = item
		self.next = None   #后继指向
		self.prev = None   #前驱指向

2.2 双向链表的实现:

双向链表的判空、求长度、遍历、查找的实现方法和单链表一样,这里就省略。列出不一样的。

def add(self, item):
	"""头插法"""
	node = Node(item)
	node.next = self.__head
	self.__head = node 
	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 = cur.next
			cur.next = node
			node.prev = cur
				


def insert(self, pos, item):
	"""指定位置添加元素
	:param pos从0开始
	"""
	if pos <= 0:
		self.add(item)
	elif pos > (self.length()-1):
		self.append(item)
	else:
		cur = self.__head
		count = 0
		while count < pos:
			count += 1
			cur = cur.next
		#  当退出循环后,cur指向pos位置
		node = Node(item)
		node.next = cur
		node.prev = cur.prev
		cur.prev.next = node
		cur.prev = node
def remove(self, item):
	"""删除结点"""
	cur = self.__head
	while cur != None:
		if cur.elem == item:
			# 先判断此结点是否是头结点,
			# 头结点
			if cur == self.__head:
				self.__head = cur.next
					if cur.next:# 链表不止一个结点
						# 判断链表是否只有一个结点,如果删的是头结点,并且只有一个结点,cur.next指向None,cue.next没有prev,错的,所以要加前面的判断是否不止一个
						cur.next.prev = None
			else:
				cur.prev.next = cur.next
				if cur.next: # 如果cur.next是存在的,才能.prev,这是对末结点的特殊情况进行判断
					cur.next.prev = cur.prev
			break
		else:
			cur = cur.next

3. 单向循环链表
在这里插入图片描述
3.1 单向循环链表结点的实现:

和单链表的实现一样,省略

3.2 单向循环链表的实现:

class SingleLinkList(object):
	"""单向循环链表"""
	def __init__(self, node = None):
		self.__head = node
		# 和单链表的构造函数有点区别,多一个回环的操作
		if node:
			node.next = node
		...
def length(self):
	"""求长度"""
	if self.is_empty():
		return 0
	# cur游标,用来移动遍历结点
	cur = self.__head
	# count记录数量
	count = 1 # 从1计数,和单链表不一样
	while cur.next != self.__head: # 注意判断末尾和单链表不一样,回环
		count += 1
		cur = cur.next
	return count
def travel(sekf):
	"""遍历"""
	if self.is_empty():
		return 
	cur = self.__head
	while cur.next != self.__head:
		print(cur.elem, end = " ")
		cur = cur.next
	# 退出循环,cur指向尾节点,但尾节点的元素未打印
	print(cur.elem)
def add(self, item):
	"""头插"""
	node = Node(item)
	if self.is_empty():
		self.__head = node
		node.next = node
	else:
		cur = self.__head
		while cur.next != self.__head:
			cur = cur.next
		# 退出循环,cur指向尾结点,需要对尾节点进行操作
		node.next = self.__head
		self.__head = node
		cur.next = self.__head
def appedn(self, item):
	"""尾插"""
	node = Node(item)
	if self.is_empty():
		self.__head = node
		node.next = node
	else:
		cur = self.__head
		while cur.next != self.__head:
			cur = cur.next
		node.next = self.__head
		cur.next = node
def insert(self, pos, item):
	"""指定位置添加
	:param pos 从0开始
	"""
	if pos <= 0:
		self.add(item)
	elif pos > (self.length()-1):
		self.append(item)
	else:
		pre = self.__head
		count = 0
		while count < (pos-1):
			count += 1
			pre = pre.next
		# 当退出循环后,pre指向pos-1位置
		node = Node(item)
		node.next = pre.next
		pre.next = node
def search(self, item):
	"""查找结点是否存在"""
	if self.is_empty():
		return False
	cur = self.__head
	while cur.next != self.__head:
		if cur.elem == item:
			return True
		else:
			cur = cur.next
		# 退出循环,cur指向尾节点,需要对尾节点进行判断
		if cur.elem == item:
			return True
		return False
		

下面算是最难理解的单循环链表的删除操作!!!很多特殊情况的判断!

def remove(self, item):
	if self.is_empty():
		return
	cur = self.__head
	pre = None
	while cur.next != self.__head:
		if cur.elem == item:
			# 先判断此结点是否是头结点
			if cur == self.__head:
				# 头结点时候
				# 找尾节点
				rear = self.__head
				while rear.next != self.__head:
					rear = rear.next
				self.__head = cur.next
				rear.next = self.__head
			else:
				# 中间结点
				pre.next = cur.next
			return
		else:
			pre = cur
			cur = cur.next
	# 退出循环,cur指向尾节点
	if cur.elem == item:
		if cur == self.__head:
			# 链表只有一个结点
			self.__head = None
		else:
			pre.next = cur.next

猜你喜欢

转载自blog.csdn.net/qq_23557563/article/details/88063475