3 链表
具体完整源码请戳这里(python3.7 包含了测试部分) 单项链表的基本操作
链表(Linked list):一种线性表。
但是不像顺序表一样连续存储数据,
而是在每一个节点(数据存储单元)里存放:
下一个节点的位置信息(即地址)。
实现灵活的内存动态管理。
3.1 单向链表
节点结构:数据元素区+(下个节点的)链接区
1. 表元素域elem用来存放具体的数据。
2. 链接域next用来存放下一个节点的位置(python中的标识)
3. 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。
节点实现
准备:在python中实现交换两个变量
a = 10
b = 20
a,b = b,a
即:a真正代表的是一个内存,可以指向任何地址的任何值,a本身没有类型
与C等语言不同!!
节点
class SingleNode(object):
""" 单链表的结点 """
def __init__(self,item):
self.item = item
self.next = None
单链表操作
- is_empty() 链表是否为空
- length() 链表长度
- travel() 遍历整个链表
- add(item) 链表头部添加元素
- append(item) 链表尾部添加元素
- insert- (pos, item) 指定位置添加元素
- remove(item) 删除节点<重复的话,删除第一个>
- search(item) 查找节点是否存在
单链表实现
基本操作
class SingleLinkList(object):
"""单链表"""
def __init__(self):
self._head = None
def is_empty(self):
"""判断链表是否为空"""
return self._head == None
def length(self):
"""链表长度"""
cur = self._head
count = 0
while cur != None:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历链表"""
cur = self._head
while cur != None:
print (cur.item)
cur = cur.next
尾部添加元素
def append(self,item):
'''链表尾部添加元素'''
node = SingleNode(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 = SingleNode(item)
node.next = self._head
self._head = node
指定位置添加元素
def insert(self,pos,item):
'''指定位置添加元素'''
if pos <= 0:
self.add(item)
elif pos > (self.length() - 1):
self.append(item)
else:
node = SingleNode(item)
count = 0
pre = self._head
while count < (pos - 1):
count += 1
pre = pre.next
node.next = pre.next
pre.next = node
删除节点
def remove(self, item):
"""删除节点"""
cur = self._head
pre = None
while cur != None:
if cur.item == item:
if not pre:
self._head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
查找节点是否存在
def search(self,item):
"""链表查找节点是否存在,并返回True或者False"""
cur = self._head
while cur != None:
if cur.item == item:
return True
cur = cur.next
return False
链表与顺序表
链表失去了顺序表随机读取的优点,且增加了结点的指针域,空间开销比较大;
但对存储空间的使用要相对灵活。
链表与顺序表的各种操作复杂度如下所示:
链表的主要耗时操作-遍历查找,删除和插入操作本身的复杂度是O(1)。
顺序表查找很快,主要耗时-拷贝覆盖。
因为除了目标元素在尾部的特殊情况,
顺序表进行插入和删除时需要对操作点之后的所有元素进行前后移位操作,
只能拷贝+覆盖。
|