1.链表
1.1 基本原理
- 节点
- 组成链表的数据格子不是连续的。可以分布在内存的各个位置。这种不相邻的格子就叫结点。
- 每个结点保存数据还保存着链表里的下一结点的内存地址。
- 链表(Linkedlist)
- 链表结构相对于顺序表可以充分利用计算机内存空间。
- 实现灵活的内存动态管理且进行扩充时不需要进行数据搬迁。
- 是一种常见的基础数据结构,是一种线性表
1.2 链表大O记法表示
操作 | 大O记法表示【最坏情况】默认采用 | 大O记法表示【最好情况】 |
---|
读取 | O(
N
N
N) | O(1) |
查找 | O(
N
N
N) | O(1) |
插入 | O(
N
N
N) | O(1) |
删除 | O(
N
N
N) | O(1) |
2. 链表操作
2.1 读取
- 链表的结点可以分布在内存的任何位置。
- 根据索引读取
- 读取值:必须先读取索引为0的链,顺着该链去找索引1。根据索引 1 的链去找索引 2…最终找到自己要读取的值。
![在这里插入图片描述](https://img-blog.csdnimg.cn/5077ea4c791846b9afaaa80567bb5ef2.png#pic_center)
2.2 查找
- 根据值查找是否存在
- 根据读取一样,在读取每个索引节点时,读取值判断是否与查找的值相等,否则读取下一个节点,直到末尾未找到值。
![在这里插入图片描述](https://img-blog.csdnimg.cn/120255a9a1d54e88b9b2c7c8f0c965e4.png#pic_center)
2.3 插入
- 开头插入:创建新节点,将新节点链表指向的下一个内存地址为原先链表头部即可
- 中间插入:创建新节点,读取链表索引0,根据索引0找到下一个节点,依此类推找到要插入的位置,将插入索引前面的索引节点链表指向的下一个内存地址为新节点位置,将新节点指向的下一个内存地址为插入索引后面的索引节点
- 末尾插入:创建新节点,读取链表索引0,根据索引0找到下一个节点,依此类推找到末尾位置,将末尾内存节点null设置为新节点的内存地址,将新节点指向的下一个内存地址设为null
![在这里插入图片描述](https://img-blog.csdnimg.cn/2473abb993674b9ca569625824655f03.png#pic_center)
2.4 删除
- 开头删除:将链表的第二个节点设置为第一个节点即可
- 中间删除:遍历链表,遍历到要删除的索引,将删除的前一个节点指向下一个内存地址重新指向删除节点的后一个节点即可
- 末尾删除:遍历链表,遍历到倒数第二个节点,将此节点指向的下一个节点地址设为null即可
![在这里插入图片描述](https://img-blog.csdnimg.cn/034265836e3546a09acc7a868b6136e4.png#pic_center)
3.链表代码实现
class Node():
def __init__(self, item):
self.item = item
self.next = None
class Link():
def __init__(self):
self._head = None
def read(self,index):
count = 0
current = self._head
while True:
if count!=index:
count += 1
current = current.next
else:
item=current.item
print(f'索引{index}的值为:{item}')
break
return item
def search(self, item):
current = self._head
find = False
count=0
while current:
if current.item == item:
find = True
print(f'值为{item}的索引为:{count}')
break
else:
current = current.next
count+=1
return find
def add(self, item):
node = Node(item)
node.next = self._head
self._head = node
def insert(self, pos, item):
node = Node(item)
current = self._head
temp = None
if pos == 0:
self.add(item)
return
for i in range(pos):
temp = current
current = current.next
temp.next = node
node.next = current
def append(self, item):
node = Node(item)
if self._head == None:
self._head = node
temp = None
current = self._head
while current:
temp = current
current = current.next
temp.next = node
def delete(self, item):
current = self._head
temp = None
if current.item == item:
self._head = current.next
return
while current:
temp = current
current = current.next
if current.item == item:
temp.next = current.next
return
def travel(self):
current = self._head
while current:
print(current.item,end='\t')
current = current.next
print('\n')
def isEmpty(self):
return self._head == None
def length(self):
count = 0
current = self._head
while current:
count += 1
current = current.next
return count
def reverse(self):
pre = self._head
cur = pre.next
next_node = cur.next
pre.next = None
while True:
cur.next = pre
pre = cur
cur = next_node
if next_node != None:
next_node = next_node.next
else:
break
self._head = pre
link = Link()
for i in range(1,6):
link.add(i)
print('头部添加元素链表为:',end='')
link.travel()
link.insert(1, 1234)
print('中间添加元素链表为【(1, 1234)】:',end='')
link.travel()
link.append(12)
print('尾部添加元素12链表为:',end='')
link.travel()
link.read(1)
link.search(4)
link.delete(3)
print('删除元素3后链表为:',end='')
link.travel()
print("链表长度为:"+str(link.length()))
print("链表反转后值为:")
link.reverse()
link.travel()
![在这里插入图片描述](https://img-blog.csdnimg.cn/eca2e6120afa44d4a4261689d0572c03.png#pic_center)