链表的定义:
不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址),而是数组由一个一个节点组成,每个节点包含:数据部分和保存下一个数据的地址。在建立数组的时候通过添加元素的操作将数据连起来。
链表分类:
- 单链表:就是由多个节点的集合共同构成一个线性序列;
- 双向链表:它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
- 循环链表:特点是链表中最后一个结点的指针域指向头结点,整个链表形成一个环。
- 双向循环链表:即在双向链表的基础上,使最后一个节点的指针域指向头节点,整个链表形成一个环。
单向链表:
创建链表的过程是建立基础的节点类,节点可用一个类来实现,然后建立一个链表类,实现对节点的操作,实现链表、
1 节点的实现:
class Node:
def __init__(self,data):
self.data = data #数据的位置
self.next = None # 保存下一个数据的地址
然后,使用节点类实现上图所示链表,
#
node1 = Node(5) #第一个节点
node1.next = Node(6) # 第二个节点
node1.next.next = Node(8)#链接第三个节点
node1.next.next.next = Node(7)#链接第4个节点
#打印数据
print(node1.data)#5
print(node1.next.data)#6
print(node1.next.next.data)#8
print(node1.next.next.next.data)#7
out:
5
6
8
7
上述过程实现过程很符合实际操作,下面用一个类来调用节点类,实现更加复杂的功能,先建立一个包含基本的类,
常见单链表的操作
- is_empty() 链表是否为空
- length() 链表长度
- travel() 遍历整个链表
- add(item) 链表头部添加元素
- append(item) 链表尾部添加元素
- insert(pos, item) 指定位置添加元素
- remove(item) 删除节点
- search(item) 查找节点是否存在
单向链表的实现:
其基本实现基类:
class Linkedlist():
def __init__(self):
self.head = None #没有元素的时候,是空的
#1判断是否为空
def is_empty(self):
pass
#2在链表首部添加元素
def add(self,elem):
pass
#3在链表的尾部添加元素
def append(self,elem):
pass
#4在指定的位置添加元素
def insert(self,pos,item):
pass
#5删除元素
def remove(self,elem):
pass
#6求链表的长度
def lengeth(self):
pass
#7查找是否包含元素elem
def search(self,elem):
pass
#8遍历链表
def travel(self):
pass
基类的实现:
1判断是否为空
#1判断是否为空
def is_empty(self):
return self.head == None # self.head is None
2 append(item) 链表尾部添加元素:
在链表的尾部添加元素,操作比较简单,先实现,即将每一个节点尾部指向下一个元素,
需要考虑的情况:1.链表是空的时,添加元素,2链表不为空时,添加元素。
程序的实现:(重点在怎么找到链表的尾部)
#2在链表首部添加元素
def add(self,elem):
node = _Node(elem)
if self.is_empty():
self.head = node
else:
cur = self.head
while cur.next != None:#判断当前节点的next是否为空,不为空,为True
cur = cur.next#将cur移动到下一个节点
cur.next = node
3 add(item) 链表头部添加元素
def add(self,elem):
node = _Node(elem)
node.next = self.head
self.head = node
4求链表的长度
#6求链表的长度
def lengeth(self):
cur = self.head
count = 0
while cur.next != None:#跳出循环后会指向最后一个节点,
#故将加法放在前面
count += 1
cur = cur.next
return count
5在指定的位置添加元素
需考虑三种情况:
- 指定为在第一元素之前
- 指定的元素位置超过链表的长度
- 指定的元素位置在链表长度范围之内
首先是插入操作过程:
#4在指定的位置添加元素
def insert(self,pos,item):
#在第一元素之前
if pos < 0:
self.add(item)
elif pos > (self.lengeth() - 1):
self.append(item)
else:
node = Node(item)
count = 0
pre = self._head
while count < (pos-1):
count += 1
pre = pre.next
node.next = pre.next
pre.next = node
最终测试代码:
class Node:
__slots__ = 'elem','next'
def __init__(self,elem):
self.elem = elem #数据的位置
self.next = None # 保存下一个数据的地址
class Linkedlist():
def __init__(self):
self.head = None #没有元素的时候,是空的
#1判断是否为空
def is_empty(self):
return self.head == None # self.head is None ,为空返回True
#2在链表首部添加元素
def add(self,elem):
node = Node(elem)
node.next = self.head
self.head = node
#3在链表的尾部添加元素
def append(self,elem):
node = Node(elem)#调用节点类。创建一个节点
#判断是否为空
if self.is_empty():
self.head = node
else:
cur = self.head
while cur.next != None:
cur = cur.next
cur.next = node
#4在指定的位置添加元素
def insert(self,pos,item):
#在第一元素之前
if pos < 0:
self.add(item)
elif pos > (self.lengeth() - 1):
self.append(item)
else:
node = Node(item)
count = 0
pre = self.head
while count < (pos-1):
count += 1
pre = pre.next
node.next = pre.next
pre.next = node
#5删除元素
def remove(self,elem):
cur = self.head
pre = None
while cur != None:
#找到指定的元素
if cur.elem == elem:
if not pre:
self.head = cur.next
else:
pre.next = cur.next
break
else:
#继续将链表的节点往后节点
pre = cur
cur = cur.next
#6求链表的长度
def lengeth(self):
cur = self.head
count = 0
while cur != None:#跳出循环后会指向最后一个节点,
#故将加法放在前面
count += 1
cur = cur.next
return count
#7查找是否包含元素elem
def search(self,elem):
cur = self.head
while cur != None:
if cur.elem == elem:
return True
cur = cur.next
return False
#8遍历链表
def travel(self):
cur = self.head
while cur != None:
print(cur.elem)
cur = cur.next
if __name__ == "__main__":
link = Linkedlist()
print(link.is_empty())
print(link.lengeth())
#在尾部添加元素
link.append(5)
link.append(6)
link.append(7)
#遍历元素
print("--遍历在尾部添加元素的后的链表----")
link.travel()
#在指定位置添加元素
link.insert(2,8)
#遍历元素
print("---遍历插入后的链表-----")
link.travel()
True
0
--遍历在尾部添加元素的后的链表----
5
6
7
---遍历插入后的链表-----
5
6
8
7