Python - 链表的数据结构



链表(Linked Lists)是一系列数据元素,它们通过链接连接在一起。每个数据元素都包含与指针形式的另一个数据元素的连接。Python 的标准库中没有链表。我们使用上一章中讨论的节点概念来实现链表的概念。

我们已经了解了如何创建 Node 类以及如何遍历 Node 的元素。在本章中,我们将研究称为单向链表的链表的类型。在这种类型的数据结构中,任意两个数据元素之间只有一个链接。我们创建这样一个列表并创建其他方法来插入、更新和删除列表中的元素。

创建链表

链表是使用我们在上一章中学习的 node 类创建的。我们创建一个 Node 对象并创建另一个类来使用此 ode 对象。我们通过 node 对象传递适当的值,以指向下一个数据元素。下面的程序创建包含三个数据元素的链接列表。在下一节中,我们将看到如何遍历链表。


class Node:
	 	def __init__(self, dataval=None):
	 	 	 self.dataval = dataval
	 	 	 self.nextval = None

class SLinkedList:
	 	def __init__(self):
	 	 	 self.headval = None

list1 = SLinkedList()
list1.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
# Link first Node to second node
list1.headval.nextval = e2

# Link second Node to third node
e2.nextval = e3

遍历链表

单向链表只能从第一个数据元素开始向前遍历。我们只需通过将下一个节点的指针分配给当前数据元素来打印下一个数据元素的值。


class Node:
	 	def __init__(self, dataval=None):
	 	 	 self.dataval = dataval
	 	 	 self.nextval = None

class SLinkedList:
	 	def __init__(self):
	 	 	 self.headval = None

	 	def listprint(self):
	 	 	 printval = self.headval
	 	 	 while printval is not None:
	 	 	 	 	print (printval.dataval)
	 	 	 	 	printval = printval.nextval

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")

# Link first Node to second node
list.headval.nextval = e2

# Link second Node to third node
e2.nextval = e3

list.listprint()

输出

执行上述代码时,它会产生以下结果 -

Mon
Tue
Wed

插入到链表中

在链表中插入元素涉及将指针从现有节点重新分配给新插入的节点。根据新数据元素是在链表的开头、中间还是结尾插入,我们有以下情况。

在开头插入

这包括将新数据节点的下一个指针指向链表的当前 head。因此,链表的当前 head 成为第二个数据元素,新节点成为链表的 head。


class Node:
	 	def __init__(self, dataval=None):
	 	 	 self.dataval = dataval
	 	 	 self.nextval = None

class SLinkedList:
	 	def __init__(self):
	 	 	 self.headval = None
# Print the linked list
	 	def listprint(self):
	 	 	 printval = self.headval
	 	 	 while printval is not None:
	 	 	 	 	print (printval.dataval)
	 	 	 	 	printval = printval.nextval
	 	def AtBegining(self,newdata):
	 	 	 NewNode = Node(newdata)

# Update the new nodes next val to existing node
	 	NewNode.nextval = self.headval
	 	self.headval = NewNode

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")

list.headval.nextval = e2
e2.nextval = e3

list.AtBegining("Sun")
list.listprint()

输出

执行上述代码时,它会产生以下结果 -

Sun
Mon
Tue
Wed

在末尾插入

这涉及将链表的当前最后一个节点的下一个指针指向新的数据节点。因此,链表的当前最后一个节点成为倒数第二个数据节点,新节点成为链表的最后一个节点。


class Node:
	 	def __init__(self, dataval=None):
	 	 	 self.dataval = dataval
	 	 	 self.nextval = None
class SLinkedList:
	 	def __init__(self):
	 	 	 self.headval = None
# Function to add newnode
	 	def AtEnd(self, newdata):
	 	 	 NewNode = Node(newdata)
	 	 	 if self.headval is None:
	 	 	 	 	self.headval = NewNode
	 	 	 	 	return
	 	 	 laste = self.headval
	 	 	 while(laste.nextval):
	 	 	 	 	laste = laste.nextval
	 	 	 laste.nextval=NewNode
# Print the linked list
	 	def listprint(self):
	 	 	 printval = self.headval
	 	 	 while printval is not None:
	 	 	 	 	print (printval.dataval)
	 	 	 	 	printval = printval.nextval

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")

list.headval.nextval = e2
e2.nextval = e3

list.AtEnd("Thu")

list.listprint()

输出

执行上述代码时,它会产生以下结果 -

Mon
Tue
Wed
Thu

插入两个数据节点之间

这涉及将特定节点的指针更改为指向新节点。这可以通过传入新节点和现有节点来实现,然后插入新节点。因此,我们定义了一个额外的,它将新节点的下一个指针更改为中间节点的下一个指针。然后将新节点分配给中间节点的下一个指针。


class Node:
	 	def __init__(self, dataval=None):
	 	 	 self.dataval = dataval
	 	 	 self.nextval = None
class SLinkedList:
	 	def __init__(self):
	 	 	 self.headval = None

# Function to add node
	 	def Inbetween(self,middle_node,newdata):
	 	 	 if middle_node is None:
	 	 	 	 	print("The mentioned node is absent")
	 	 	 	 	return

	 	 	 NewNode = Node(newdata)
	 	 	 NewNode.nextval = middle_node.nextval
	 	 	 middle_node.nextval = NewNode

# Print the linked list
	 	def listprint(self):
	 	 	 printval = self.headval
	 	 	 while printval is not None:
	 	 	 	 	print (printval.dataval)
	 	 	 	 	printval = printval.nextval

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Thu")

list.headval.nextval = e2
e2.nextval = e3

list.Inbetween(list.headval.nextval,"Fri")

list.listprint()

输出

执行上述代码时,它会产生以下结果 -

Mon
Tue
Fri
Thu

删除项目

我们可以使用该节点的键删除现有节点。在下面的程序中,我们找到要删除的节点的前一个节点。然后,将此节点的下一个指针指向要删除的节点的下一个节点。


class Node:
	 	def __init__(self, data=None):
	 	 	 self.data = data
	 	 	 self.next = None
class SLinkedList:
	 	def __init__(self):
	 	 	 self.head = None

	 	def Atbegining(self, data_in):
	 	 	 NewNode = Node(data_in)
	 	 	 NewNode.next = self.head
	 	 	 self.head = NewNode

# Function to remove node
	 	def RemoveNode(self, Removekey):
	 	 	 HeadVal = self.head
	 	 	 	 	
	 	 	 if (HeadVal is not None):
	 	 	 	 	if (HeadVal.data == Removekey):
	 	 	 	 	 	 self.head = HeadVal.next
	 	 	 	 	 	 HeadVal = None
	 	 	 	 	 	 return
	 	 	 while (HeadVal is not None):
	 	 	 	 	if HeadVal.data == Removekey:
	 	 	 	 	 	 break
	 	 	 	 	prev = HeadVal
	 	 	 	 	HeadVal = HeadVal.next

	 	 	 if (HeadVal == None):
	 	 	 	 	return

	 	 	 prev.next = HeadVal.next
	 	 	 HeadVal = None

	 	def LListprint(self):
	 	 	 printval = self.head
	 	 	 while (printval):
	 	 	 	 	print(printval.data),
	 	 	 	 	printval = printval.next

llist = SLinkedList()
llist.Atbegining("Mon")
llist.Atbegining("Tue")
llist.Atbegining("Wed")
llist.Atbegining("Thu")
llist.RemoveNode("Tue")
llist.LListprint()

输出

执行上述代码时,它会产生以下结果 -

Thu
Wed
Mon