一、双向链表
-
双向链表
-
既可以从头遍历到尾, 又可以从尾遍历到头
-
也就是链表相连的过程是双向的. 那么它的实现原理, 你能猜到吗?
-
一个节点既有向前连接的引用, 也有一个向后连接的引用.
-
双向链表可以有效的解决单向链表中提到的问题.
-
双向链表有什么缺点呢?
-
每次在插入或删除某个节点时, 需要处理四个节点的引用, 而不是两个. 也就是实现起来要困难一些
-
并且相当于单向链表, 必然占用内存空间更大一些.
-
但是这些缺点和我们使用起来的方便程度相比, 是微不足道的.
-
-
-
双向连接的图解:
1.双向链表的创建
-
创建一个双向链表的类
#创建节点类 class Node: def __init__(self,element): self.element = element self.next = None self.prev = None #创建双向链表类 class doubly_linked_list: #定义属性 def __init__(self, element): self.length = 0 self.head = None self.tail = None #定义操作方法: #def x1(self): #def x2(self):
-
代码解析:
-
Node中添加一个self.prev属性,该属性指向上一个结点
-
另外添加一个self.tsil属性,用于指向末尾的结点
-
2.尾部追加数据
def append(self,element): # 1.根据元素创建节点 newNode = Node(element) # 2.判断列表是否为空列表 if self.head == None: self.head = newNode self.tail = newNode else: self.tail.next = newNode newNode.prev = self.tail self.tail = newNode length + 1 self.length+=1
-
代码解析:
-
代码1部分通过元素创建新的节点.
-
代码2部分分两种情况.
-
情况一: 链表原来为空
-
链表中原来如果没有数据, 那么直接让head和tail指向这个新的节点即可.
-
-
情况二: 链表中已经存在数据
-
将数据默认追加到尾部.
-
-
3.任意位置插入
def insert(self,position, element): #判断越界的问题 if position < 0 or position > self.length: return False newNode = Node(element) if position == 0: #判断链表是否为空 if self.head == None: self.head = newNode self.tail = newNode else: self.head.prev = newNode newNode.next = self.head self.head = newNode elif position == self.length: self.tail.next = newNode newNode.prev = self.tail self.tail = newNode else: # 在中间位置插入数据 index = 0 current = self.head previous = None #查找正确的位置 while index < position: previous = current current = current.next index+=1 #交换节点的指向顺序 newNode.next = current newNode.prev = previous current.prev = newNode previous.next = newNode self.length+=1 return True
-
代码深度解析, 代码比较复杂, 我们分成三种情况:
-
情况一: 将元素插入到头部(position === 0)
-
- 情况二: 将元素插入到尾部(position === length)
- 情况三: 将元素插入到中间位置
4.位置移除数据
def removeAt(self, position): # 判断越界的问题 if position < 0 or position >= self.length: return None # 判断移除的位置 current = self.head if position == 0: if self.length == 1: self.head = None self.tail = None else: self.head = self.head.next self.head.prev = None elif position == self.length - 1: current = self.tail self.tail = self.tail.prev self.tail.next = None else: index = 0 previous = None while index < position: previous = current current = current.next index += 1 previous.next = current.next current.next.prev = previous length-1 self.length -= 1 return current.element
-
情况一: 删除头部的元素
-
情况二: 删除尾部的元素
-
情况三: 删除中间位置的元素
5.获取元素位置
# 根据元素获取再链表中第一个出现的位置, 没有返回 - 1 def indexOf(self,element): #1.定义变量保存信息 current = self.head index = 0 #2.查找正确的信息 while current: if current.element == element: return index index+=1 current = current.next #3.来到这个位置, 说明没有找到, 则返回-1 return -1
6.根据元素删除
#根据元素删除 def remove(self,element): index = self.indexOf(element) return self.removeAt(index)
7.其他方法实现
# 判断是否为空 def isEmpty(self): return self.length == 0 # 获取链表长度 def size(self): return self.length # 获取第一个元素 def getHead(self): return self.head.element # 获取最后一个元素 def getTail(self): return self.tail.element