双向链表:每个个节点有两个链表;一个指向前一个节点,当此节点为第一个时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值

双链表的操作
| 方法名 | 说明 |
|---|---|
| is_empty() | 链表是否为空 |
| length() | 链表长度 |
| travel() | 遍历整个链表 |
| add(item) | 链表头部添加元素 |
| append(item) | 链表尾部添加元素 |
| insert(pos,item) | 指定位置添加元素 |
| remove(item) | 删除节点 |
| search(item) | 查找节点是否存在 |
构造节点
class Node(object):def __init__(self,item):构造函数初始化self.prev=None #定义前驱节点self.elem=item #定义传入的值数据区self.next=None #定义后继节点
链表的构造
class DoubleLinkList(object):def __init__(self,node=None):self.__head=node
方法与单链表类似
1.判断链表是否为空
def is_empty(self):return (self.__head==None)
方法与单链表类似
2.计算链表长度
def length(self):cur = self.__headcount=0while cur != None:count+=1cur=cur.nextreturn count
方法与单链表类似
3.遍历链表
def travel(self):cur = self.__headwhile cur != None:print(cur.elem)cur=cur.next
方法与单链表类似
4.尾部添加元素
尾部插入也和单链表类似,需要创建一个指针,进行循环
- 将尾结点指向node的next指向新节点node
- 再将节点的prev指向前一个节点(cur所指向的)

def append(self,item):node=Node(item)cur=self.__headwhile cur.next !=None: #注意是cur.nextcur=cur.next#找到了。就赋值cur.next=nodenode.prev=cur
特殊情况
当链表为空时
插入的节点就是头节点
可以调用is_empty()函数来判断是否为空
def append(self,item):node=Node(item)if self.is_empty():self.__head=nodeelse:while cur.next !=None:cur=self.__headcur=cur.nextcur.next=nodenode.prev=cur
5.头部添加元素
方法一:
- 将传入节点next于指向头节点所指向的节点

- 再将头节点指针指向新建节点

- 最后将头节点所指向的节点的prev(后继节点)指向传入的节点

def add(self,item):node=Node(item)node.next=self.__headnode.next.prev=node# slef.__head.prev=nodeself.__head=node
特殊情况
当链表为空时
插入的节点就是头节点
可以调用is_empty()函数来判断是否为空
def add(self,item):#创建节点node=Node(item)if self.is_empty():self.__head=nodeelsenode.next=self.__headself.__head=nodenode.next.prev=node
6.指定位置添加元素
单链表类似,但不同的是,双链表有前驱,可以找到上一个节点,所以不需要再定义指针prev
基本思路:
- 将传入的节点next指向cur

- 将插入的节点的前驱指向cur的前驱prev

- 打断原本的链接,将前面的节点的next指向插入的node

- 再将cur的前驱prev指向插入的节点

def insert(self,pos,item):node=Node(item)cur=self.__headcount=0while count < (pos-1):count+=1cur=cur.nextnode.next=curnode.prev=cur.prevcur.prev.next=nodecur.prev=node
特殊情况
当插入的数为负数pos<=0
- 调用头插法self.add()
当插入的数大于链表的长度(尾节点)pos>length()-1【0开始,长度为length-1】
- 注意位置≠链表长度【pos=length()-1:就代表时pos-1处断开节点】
- 调用尾插法self.append()
这时的没有所谓的pre指针,所有插入条件也不需要为pos-1作为条件;双链表有前驱节点可以直接向,所以插入时候,直接在pos的位置插入,即当count=pos,就进行插入操作
def insert(self,pos,item):node=Node(item)if pos<=0:self.add(item)elif pos >self.length()-1:self.append(item)else:count=0cur=self.__headwhile count <pos:count+1cur=cur.nextnode.next=curnode.prev=cur.prevcur.prev.next=nodecur.prev.node
7.查找元素
与单链表类似
def search(self,item):cur=self.__headwhile cur != None:if cur.elem==item:return Trueelse:cur=cur.nextreturn False
8.删除节点
基本思路:
定义指针cur
当删除的数是cur所指
把cur的前节点指向cur的后节点
把cur的后节点指向cur的前节点
def remove(self,item):cur=self.__headwhile cur != None:if cur.elem==item:cur.prev.next=cur.nextcur.next.prev=cur.prevbreakelse:cur=cur.next
特殊情况
当删除的是首节点
情况1:当是首节点
需要判要删除节点的后一个节点是否存在
存在就按照基本思路解决
不存在就不要写cur.next.prev=None


def remove(self, item):cur=self.__headwhile cur !=None:if cur.elem==item:if self.__head==cur:slef.__head=cur.nextif cur.next:cur.next.prev=Noneelse:cur.prev.next=cur.nextcur.next.prev=cur.prevbreakelse:cur=cur.next
情况2:当删除的节点时最后的节点
需要判要删除节点的后一个节点是否存在
存在就按照基本思路解决
不存在就不要写cur.next.prev=None

def remove(self,item):#定义curcur=self.___head#指向头节点while cur !=None: #循环找if cur.elem==item: #找到了if cur ==self.__head: #找到的是头节点self.__head=cur.nextif cur.next: #cur.next不为Nonecur.next.prev=Noneelse: #找到的不是头节点(尾结点或中间节点)cur.prev.next=cur.next#找到的不是尾结点if cur.next:cur.next.prev=cur.prevbreakelse:cur=cur.next #没找到,直接移到下一位
