摘要
- 所谓数据都是要存储在内存上的,而内存则是一个连续的存储空间。
- 本文使用数据基本类型,实现链表的三种形式(链表不仅仅这三种形式)。
- 需要定义两个类,一个是节点类,一个是实现类。
- python中的列表使用的数据结构是:顺序表。而且具备以下几个特点:–分离式存储(数据区变化,表头信息的地址空间是不变的),–元素外置(支持不同数据类型的存储和删改),–动态顺序表(扩充策略是:加倍(每一次加倍的时候,可能这个连续的地址空间是要更换的)))。
- 表头是什么?它存储着数据区容量和数量信息。
- 也正因为python list数据结构的特点,所以它极为方便和优雅,但是也正因为此,它的效率很慢。
- 双向链表还有继续拓展的空间:例如双向循环链表。
- 理解代码需要参考以下几点:
1、先算等号右边的
2、等号只是引用
3、一切皆对象
4、一个节点的第二个属性,存储了下个节点的引用。
5、核心思想是:改变节点中链接区的指向。
6、若想动节点,先动自己的节点(要操作的数据),链表上的节点晚点动(原本的数据)。
代码片1:单向链表
class Node(object):
'''节点'''
def __init__(self, elem):
self.elem = elem
self.next = None
class SingleLinkList(object):
'''单链表'''
def __init__(self, node=None):
self.__head = node
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 travel(self):
"""遍历整个列表"""
cur = self.__head
while cur is not None:
print(cur.elem, end=' ')
cur = cur.next
print('')
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():
self.__head = node
else:
cur = self.__head
while cur.next is not None:
cur = cur.next
cur.next = node
def insert(self, pos, item):
"""
指定位置插入元素
:param pos:从零开始,在哪添加元素
:param item: 添加的元素
"""
if pos <= 0:
self.add(item)
elif pos > self.length() - 1:
self.append(item)
else:
pre = self.__head
count = 0
while count < (pos - 1):
count += 1
pre = pre.next
node = Node(item)
node.next = pre.next
pre.next = node
def remove(self, item):
"""删除节点"""
pre = self.__head
if pre.elem == item:
self.__head = pre.next
else:
while pre.next is not None:
if pre.next.elem == item:
pre.next = pre.next.next
else:
pre = pre.next
def remove_2(self, item):
'''删除节点方法2'''
cur = self.__head
pre = None
while cur is not None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
def search(self, item):
"""查找节点是否存在"""
cur = self.__head
while cur is not None:
if item == cur.elem:
return True
else:
cur = cur.next
return False
def __call__(self, *args, **kwargs):
'''打印该列表'''
cur = self.__head
if cur is None:
return None
else:
s_tr = ''
while cur is not None:
if cur.next is not None:
s_tr += str(cur.elem) + ','
else:
s_tr += str(cur.elem)
cur = cur.next
s_tr = '<' + s_tr + '>'
return s_tr
if __name__ == '__main__':
ll = SingleLinkList()
print(ll.is_empty())
print(ll.length())
print(ll())
ll.append(1)
print(ll.is_empty())
print(ll.length())
ll.append(2)
ll.append(3)
ll.append(4)
ll.append(5)
ll.append(6)
ll.add(2)
ll.insert(2, 7)
print(ll.search(7))
ll.remove(2)
ll.remove_2(7)
ll.travel()
print(ll())
代码片2:双向链表
class Node(object):
"""节点"""
def __init__(self, item):
self.elem = item
self.next = None
self.prev = None
class DoubleLinkList(object):
"双链表"
def __init__(self, node=None):
self.__head = node
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 travel(self):
"""遍历整个列表"""
cur = self.__head
while cur is not None:
print(cur.elem, end=' ')
cur = cur.next
print('')
def add(self, item):
"""链表头部添加元素,头插法"""
node = Node(item)
node.next = self.__head
self.__head = node
node.next.prev = node
def append(self, item):
"""尾部添加元素,尾插法"""
node = Node(item)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next is not None:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, pos, item):
"""
指定位置插入元素
:param pos:从零开始,在哪添加元素
:param item: 添加的元素
"""
if pos <= 0:
self.add(item)
elif pos > self.length() - 1:
self.append(item)
else:
cur = self.__head
count = 0
while count < pos:
count += 1
cur = cur.next
node = Node(item)
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
def remove_2(self, item):
'''删除节点方法2'''
cur = self.__head
while cur is not None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
if cur.next:
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next:
cur.next.prev = cur.prev
break
else:
cur = cur.next
def search(self, item):
"""查找节点是否存在"""
cur = self.__head
while cur is not None:
if item == cur.elem:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
ll = DoubleLinkList()
print(ll.is_empty())
print(ll.length())
ll.append(1)
print(ll.is_empty())
print(ll.length())
ll.append(2)
ll.append(3)
ll.append(4)
ll.append(5)
ll.append(6)
ll.add(2)
ll.insert(2, 7)
print(ll.search(7))
ll.remove_2(2)
ll.remove_2(7)
ll.travel()
代码片3:单向循环链表
class Node(object):
'''节点'''
def __init__(self, elem):
self.elem = elem
self.next = None
class SingleCycleLinkList(object):
'''单向循环链表'''
def __init__(self, node=None):
self.__head = node
if node:
node.next = node
def is_empty(self):
'''链表是否为空'''
return self.__head is None
def length(self):
"""链表长度"""
if self.is_empty():
return 0
else:
cur = self.__head
count = 1
while cur.next != self.__head:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历整个列表"""
if self.is_empty():
return
else:
cur = self.__head
while cur.next != self.__head:
print(cur.elem, end=' ')
cur = cur.next
print(cur.elem)
def add(self, item):
"""链表头部添加元素,头插法"""
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
self.__head = node
cur.next = self.__head
def append(self, item):
"""尾部添加元素,尾插法"""
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
cur.next = node
def insert(self, pos, item):
"""
指定位置插入元素
:param pos:从零开始,在哪添加元素
:param item: 添加的元素
"""
if pos <= 0:
self.add(item)
elif pos > self.length() - 1:
self.append(item)
else:
pre = self.__head
count = 0
while count < (pos - 1):
count += 1
pre = pre.next
node = Node(item)
node.next = pre.next
pre.next = node
def remove_2(self, item):
'''删除节点方法2'''
if self.is_empty():
return
cur = self.__head
pre = None
while cur.next != self.__head:
if cur.elem == item:
if cur == self.__head:
rear = self.__head
while rear.next != self.__head:
rear = rear.next
self.__head = cur.next
rear.next = self.__head
else:
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
if cur.elem == item:
if cur == self.__head:
self.__head = None
else:
pre.next = cur.next
def search(self, item):
"""查找节点是否存在"""
if self.is_empty():
return False
cur = self.__head
while cur.next != self.__head:
if item == cur.elem:
return True
else:
cur = cur.next
if cur.elem == item:
return True
else:
return False
if __name__ == '__main__':
ll = SingleCycleLinkList()
print(ll.is_empty())
print(ll.length())
ll.append(1)
print(ll.is_empty())
print(ll.length())
ll.append(2)
ll.append(3)
ll.append(4)
ll.append(5)
ll.append(6)
ll.add(2)
ll.insert(2, 7)
print(ll.search(7))
ll.remove_2(2)
ll.remove_2(7)
ll.travel()
print(ll.search(7))
补充
- 顺序表和链表的核心区别:顺序表需要一段连续的存储空间(可以通过计算便能得出数据所在得位置),而链表则是利用了节点的指向,从而可以存储在零散的内存上(只能利用指向来获取对应数据得位置)。
- 因为数据结构的不同,所以,显而易见的是:顺序表和链表修改数据时得时间复杂度是不同的。(具体参考百度一下)
- 栈和队列需要依靠基本的“容器”来设计出来(可以是链表,也可以是顺序表)
- 栈的特点:只有一端进出,先进后出(像杯子)
- 队列的特点:一端进,一端出,先进先出(像管道)。
- 本文仅服务作者本人