数据结构与算法--双向链表

Posted bbs2013

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法--双向链表相关的知识,希望对你有一定的参考价值。

双向链表类:

单链表只有一个方向的链接,只能做一个方向的扫描和逐步操作。

两端插入和删除操作都能高效完成,就必须修改结点的基本设计,加入另一个方向的链接。

结点增加了一个链接域,增加的空间开销与结点数成正比。

技术图片

  p.prev.next = p.next

  p.next.prev = p.prev

技术图片

 

 技术图片

 

 双向链表:头结点和尾结点都为空。

技术图片

 

 add:

技术图片

 

1.# 将node的next指向_head的头节点     node.next = self._head

2.# 将初始的_head 指向node                self_head = node

3.# 将_head的头节点的prev指向node   node.next.prev = node  (由于1的原因:self._head.prev = node)

 

append:

技术图片

 

1.# 将尾节点cur的next指向node       cur.next = node
2.# 将node的prev指向cur                  node.prev = cur

 insert:

技术图片

 

 

2. # 将node的prev指向cur          node.next  = cur

1.   node.prev  = cur.prev 

3.  cur.prev = node                                cur.prev.next = node

4.  node.perv.next = node                cur.prev = node

 

remove:

技术图片

 

 

1. cur.prev.next = cur.next

2.cur.next.prev = cur.prev

若删除为首节点:

1. cur.prev.next = cur.next

2. cur.next.prev = None

class Node(object):
    """双向链表节点"""
    def __init__(self, item):
        self.item = item    #与单链表向比,多了前驱
        self.next = None    
        self.prev = None

class DLinkList(object):
    """双向链表"""
    def __init__(self  ):
        self._head = None  #构造函数,双向链表任然用存在head的属性

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None  # 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
        print ("")

    def add(self, item):
        """头部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 将node的next指向_head的头节点
            node.next = self._head
            # 将_head的头节点的prev指向node
            self._head.prev = node
            # 将_head 指向node
            self._head = node

    def append(self, item):
        """尾部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 移动到链表尾部
            cur = self._head
            while cur.next != None:
                cur = cur.next
            #当推出循环后,cur当前为原最后结点
            # 将尾节点cur的next指向node
            cur.next = node
            # 将node的prev指向cur
            node.prev = cur



    def search(self, item):
        """查找元素是否存在"""
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False


    def insert(self, pos, item):
        """在指定位置添加节点"""
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 移动到指定位置的前一个位置,讲解的时候用的是后一个位置,注意区分。
            while count < (pos-1):
                count += 1
                cur = cur.next
            # 将node的prev指向cur
            node.prev = cur
            # 将node的next指向cur的下一个节点
            node.next = cur.next
            # 将cur的下一个节点的prev指向node
            cur.next.prev = node
            # 将cur的next指向node
            cur.next = node


    def remove(self, item):
        """删除元素"""
        if self.is_empty():
            return
        else:
            cur = self._head
            if cur.item == item:
                # 如果首节点的元素即是要删除的元素
                if cur.next == None:        #判断链表是否只有一个节点
                    # 如果链表只有这一个节点
                    self._head = None
                else:
                    # 将第二个节点的prev设置为None
                    cur.next.prev = None
                    # 将_head指向第二个节点
                    self._head = cur.next
                return
            while cur != None:
                if cur.item == item:
                    # 将cur的前一个节点的next指向cur的后一个节点
                    cur.prev.next = cur.next
                    # 将cur的后一个节点的prev指向cur的前一个节点
                    cur.next.prev = cur.prev
                    break
                cur = cur.next



if __name__ == "__main__":
    ll = DLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.insert(2, 4)
    ll.insert(4, 5)
    ll.insert(0, 6)
    print ("length:", ll.length())
    ll.travel()
    print (ll.search(3))
    print (ll.search(4))
    ll.remove(1)
    print ("length:",ll.length())
    ll.travel()

 

以上是关于数据结构与算法--双向链表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法-线性表之双向链表

双向链表简单实现--数据结构与算法纪录片第一记

数据结构与算法系列五(双向链表)

Python数据结构与算法(2.4)——双向链表

数据结构与算法: 约瑟夫问题(丢手绢)

数据结构与算法--双向链表