python不像C语言,没有指针类型,那么如何实现链表之类的数据结构呢。我们可以利用python变量创建的特点,来进行实现。
python创建一个变量名,实际上是给一个值添加了一个标识符,所以会出现以下情况:
a = [1,2,3]
b = a
b.append(4)
print(a)
print(b)
得到的输出是
>>>a
[1,2,3,4]
>>>b
[1,2,3,4]
这是因为,a和b都是对列表的引用,尽管我们使用了a=b来进行赋值,但是只是为那个列标添加了一个标识符,所以当a的值改变后,b的值也会改变。这种行为有点“像”C语言中的指针。
但是并不是每一种类型都是如此,python为一些“热门”的整数预留了地址,所以会出现以下情况
a = 1
b = a
a = 2
print(a,b)
得到的结果却是
>>>a
2
>>>b
1
python为1和2这两个数字留好了特定的内存地址,所以给a重新赋值2的时候,相当于把a这个标签“贴到”了数字2的地址上,而b这个标签仍然“贴在”数字1的地址上,所以不会出现和上面列表一样的情况。感兴趣的读者可以编写一段代码,找出python为哪些数字预留了特定的地址。
有了上面的基础,我们可以使用python来实现一个单链表
class Node:
def __init__(self,data=None):
self.data = data
self.next = None
这里定义了一个节点类,节点有两个属性,分别是值和下一个节点的地址,这里默认值为None
class LinkList(Node):
def __init__(self,*args):
super().__init__(0)
for i in args[::-1]:
self.headInsert(i)
self.data += 1
def headInsert(self,value):
node = Node(value)
node.next = self.next
self.next = node
def output(self,end="\r"):
tem = self.next
first = True
while tem!=None:
if first:
print(tem.data,end="")
first = False
else:
print("->",tem.data,end="")
tem = tem.next
print(end)
def endInsert(self,value):
tem = self
while tem.next!=None:
tem = tem.next
node = Node(value)
node.next = None
tem.next = node
def insert(self,pos,value)->bool:
if pos<0|pos>self.data-1:
return False
tem = self
for i in range(pos):
tem = tem.next
node = Node(value)
node.next = tem.next
tem.next = node
self.data += 1
return True
这里定义了一个链表类型,我们实现了一些基本方法,包括头插,尾插,插入,遍历输出,下面来测试一下代码
l = LinkList(1,2,3)
l.output()
输出结果如下
1-> 2-> 3
这就是单链表的创建,如果想创建循环单链表,则只需要将节点的默认值设置为self,然后在尾插法的部分把尾节点的next属性赋值为self,然后修改尾插和遍历输出的循环结束条件为:tem!=self即可
下面我们来创建一个双链表
class Node:
def __init__(self,value=None):
self.data = value
self.next = None
self.pre = None
节点的类型略有变化,添加了一个前驱的属性
class DoubleLinkList(Node):
def __init__(self,*args):
super().__init__(0)
for i in args[::-1]:
self.headInsert(i)
self.data+=1
def headInsert(self,value):
node = Node(value)
node.next = self.next
node.pre = self
if self.next != None:
self.next.pre = node
self.next = node
def output(self,end="\r"):
tem = self.next
first = True
while tem!=None:
if first:
print(tem.data,end="")
first = False
else:
print("->",tem.data,end="")
tem = tem.next
print(end)
然后是双链表类,同样实现了头插法来辅助创建,双链表的插入操作和尾插操作于单链表相似,不再写出。来测试一下双链表的代码
dl = DoubleLinkList(1,4,2,3)
dl.output()
print(dl.next.next.next.next.pre.data)
print(dl.data)
结果如下
1-> 4-> 2-> 3
2
4