一、链表简介
链表是一种在存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现。链表是由一系列的结点组成,结点可以在运行时动态生成。每个结点包含两部分:数据域与指针域。数据域存储数据元素,指针域存储下一结点的指针。
二、单向链表
单向链表也叫单链表,是链表中最简单的形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
head 保存首地址,item 存储数据,next 指向下一结点地址。
链表失去了序列的随机读取优点,同时链表增加了指针域,空间开销也较大,但它对存储空间的使用要相对灵活。
列如:有一堆数据[1,2,3,5,6,7],要在3和5之间插入4, 如果用数组,需要将5之后的数据都往后退一位,然后再插入4,这样非常麻烦,但是如果用链表,我就直接在3和5之间插入4就行。
1. 定义链表
定义节点
结点的数据结构为数据元素(item)与 指针(next)
class Node(object): # 定义类用大写字母开头,继承object类
"""单链表的结点"""
def __init__(self, item): # 定义的类的方法中第一个参数永远是self
# item存放数据元素
self.item = item # 把认为必备的属性强制写进__init__方法里,在__init__方法内部,把类的属性绑定到self
# next是下一个节点的标识
self.next = None
定义链表
链表需要具有首地址指针head。
class SingleLinkList(object):# 定义类用大写字母开头
"""单链表"""
def __init__(self):
self.__head = None
示例:创建链表
if __name__ == '__main__':
# 创建链表
link_list = SingleLinkList()
# 创建结点
node1 = Node(1)
node2 = Node(2)
# 将结点添加到链表
link_list._head = node1
# 将第一个结点的next指针指向下一结点
node1.next = node2
# 访问链表
print(link_list._head.item) # 访问第一个结点数据
print(link_list._head.next.item) # 访问第二个结点数据
是不是感觉很麻烦,所以我们要在链表中增加操作方法。
- is_empty() 链表是否为空
- length() 链表长度
- items() 获取链表数据迭代器
- add(item) 链表头部添加元素
- append(item) 链表尾部添加元素
- insert(pos, item) 指定位置添加元素
- remove(item) 删除节点
- find(item) 查找节点是否存在
在链表类中加入方法
class Singlelinklist(object):
"""单链表"""
def __init__(self):
self._head=None
def is_empty(self):
"""判断链表是否为空"""
return self._head is None
def length(self):
"""链表长度"""
cur=self._head
count=0
while cur is not None:
count+=1
cur=cur.next
return count
def items(self):
"""遍历链表"""
cur=self._head
while cur is not None:
yield cur.item # yield 的函数在 Python 中被称之为 generator(生成器)
cur=cur.next
def add(self,item):
"""向链表头部添加元素"""
node=Node(item)
node.next=self._head
self._head=node
def append(self,item):
"""尾部添加元素"""
node=Node(item)
# 先判断是否为空链表
if self.is_empty():
# 空链表,_head 指向新结点
self._head=node
else:
# 不是空链表,则找到尾部,将尾部next结点指向新结点
cur=self._head
while cur.next is not None:
cur=cur.next
cur.next=node
def insert(self,index,item):
"""指定位置插入元素"""
# 指定位置在第一个元素之前,在头部插入
if index<=0:
self.add(item)
# 指定位置超过尾部,在尾部插入
elif index>(self.length()-1):
self.append(item)
else:
# 创建元素结点
node=Node(item)
cur=self._head
# 循环到需要插入的位置
for i in range(index-1):
cur=cur.next
node.next=cur.next
cur.next=node
def remove(self,item):
"""删除节点"""
cur=self._head
pre=None
while cur is not None:
# 找到指定元素
if cur.item==item:
# 如果第一个就是删除的节点
if not pre:
# 将头指针指向头节点的后一个节点
self._head=cur.next
else:
# 将删除位置前一个节点的next指向删除位置的后一个节点
pre.next=cur.next
return True
else:
pre=cur
cur=cur.next
def find(self,item):
return item in self.items()
实例化链表
if __name__ == '__main__':
link_list = Singlelinklist()
# 向链表尾部添加数据
for i in range(5):
link_list.append(i)
# 向头部添加数据
link_list.add(6)
# 遍历链表数据
for i in link_list.items():
print(i, end='\t')