链表
为什么需要链表
顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活
链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理
链表定义
链表(lingked list)是一种常见的基础数据结构,是一种线性表,但是不想顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个位置信息(即地址)
单向链表
python中变量标识的本质
python中变量是一个地址,其中存储的是指向内容的地址,“=”右边为引用操作。
单向链表的基本操作
class Node(object):
def __init__(self, item):
self.item = item
self.next = None
class SingleLinkedList(object):
def __init__(self, node = None):
self._head = node
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 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 != None:
Cur = Cur.next
Cur.next = node
def insert(self, pos, item):
if pos <= 0:
self.add(item)
elif pos > (self.length()):
self.append(item)
else:
node = Node(item)
count = 1
pre = self._head
while count <= (pos - 1):
count +=1
pre = pre.next
node.next = pre.next
pre.next = node
def search(self, item):
cur = self._head
while cur != None:
if cur.item == item:
return True
else:
cur = cur.next
return False
def remove(self, item):
pre = self._head
if pre.item == item:
self._head = pre.next
else:
while (pre.next.item != item):
pre = pre.next
pre.next = pre.next.next
if __name__ == '__main__':
sll = SingleLinkedList()
print(sll.is_empty())
print(sll.length())
sll.append(1)
# print(sll.is_empty())
# print(sll.length())
sll.append(2)
sll.append(3)
sll.append(4)
# print(sll.is_empty())
# print(sll.length())
# sll.add(8)
sll.insert(-1,9)
sll.insert(3,12)
sll.insert(9,100)
# sll.travel()
print(sll.search(100))
sll.remove(3)
sll.travel()
链表与顺序表的对比
操作 | 链表 | 顺序表 |
---|---|---|
访问元素 | O(n) | O(1) |
在头部插入/删除 | O(1) | O(n) |
在尾部插入/删除 | O(n) | O(1) |
在中间插入/删除 | O(n) | O(n) |
链表失去了顺序表的随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大,但对存储空间的使用要相对相对灵活
双向链表
双向链表操作
class Node(object):
def __init__(self, item):
self.item = item
self.prev = None
self.next = None
class DoubleLinkedList(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 != None :
count += 1
Cur = Cur.next
return count
def travel(self):
Cur = self._head
while Cur != None:
print(Cur.item)
Cur = Cur.next
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 != None:
Cur = Cur.next
Cur.next = node
node.prev = Cur
def insert(self, pos, item):
if pos <= 0:
self.add(item)
elif pos > (self.length()):
self.append(item)
else:
node = Node(item)
count = 1
pre = self._head
while count <= (pos - 1):
count +=1
pre = pre.next
node.next = pre.next
node.prev = pre
pre.next.prev = node
pre.next = node
def search(self, item):
cur = self._head
while cur != None:
if cur.item == item:
return True
else:
cur = cur.next
return False
def remove(self, item):
pre = self._head
if pre.item == item:
self._head = pre.next
pre.next.prev = None
else:
while (pre.next.item != item):
pre = pre.next
pre.next = pre.next.next
pre.next.prev = pre
if __name__ == '__main__':
dll = DoubleLinkedList()
print(dll.is_empty())
print(dll.length())
dll.append(1)
# print(sll.is_empty())
# print(sll.length())
dll.append(2)
dll.append(3)
dll.append(4)
# print(sll.is_empty())
# print(sll.length())
# sll.add(8)
dll.insert(-1,9)
dll.insert(3,12)
dll.insert(9,100)
# sll.travel()
print(dll.search(100))
dll.remove(3)
dll.travel()
单向循环链表
单向循环链表操作
class Node(object):
def __init__(self, item):
self.item = item
self.next = None
class SingleCycleLinkedList(object):
def __init__(self, node = None):
self._head = node
def is_empty(self):
return self._head is None
def length(self):
if self.is_empty():
return 0
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
Cur = self._head
while Cur.next != self._head:
print(Cur.item, end=" ")
Cur = Cur.next
print(Cur.item)
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 = node
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
Cur.next = node
node.next = self._head
def insert(self, pos, item):
if pos <= 0:
self.add(item)
elif pos > (self.length()):
self.append(item)
else:
node = Node(item)
count = 1
pre = self._head
while count <= (pos - 1):
count +=1
pre = pre.next
node.next = pre.next
pre.next = node
def search(self, item):
if self.is_empty():
return False
cur = self._head
while cur.next != self._head:
if cur.item == item:
return True
else:
cur = cur.next
if cur.item == item:
return True
return False
def remove(self, item):
if self.is_empty():
return
cur = self._head
pre = None
while cur.next != self._head:
if cur.item == 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
break
else:
pre = cur
cur = cur.next
#尾节点
if cur.item == item:
if cur == self._head:
self._head = None
else:
pre.next = cur.next
if __name__ == '__main__':
sll = SingleCycleLinkedList()
print(sll.is_empty())
print(sll.length())
sll.append(1)
# print(sll.is_empty())
# print(sll.length())
sll.append(2)
sll.append(3)
sll.append(4)
# print(sll.is_empty())
# print(sll.length())
# sll.add(8)
sll.insert(-1,9)
sll.insert(3,12)
sll.insert(9,100)
# sll.travel()
print(sll.search(100))
sll.remove(3)
sll.travel()