zoukankan      html  css  js  c++  java
  • 数据结构与算法--双向链表

    双向链表类:

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

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

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

      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()
  • 相关阅读:
    nullnullConnecting with WiFi Direct 与WiFi直接连接
    nullnullUsing WiFi Direct for Service Discovery 直接使用WiFi服务发现
    nullnullSetting Up the Loader 设置装载机
    nullnullDefining and Launching the Query 定义和启动查询
    nullnullHandling the Results 处理结果
    装置输出喷泉装置(贪心问题)
    数据状态什么是事务?
    停止方法iOS CGD 任务开始与结束
    盘文件云存储——金山快盘
    函数标识符解决jQuery与其他库冲突的方法
  • 原文地址:https://www.cnblogs.com/BBS2013/p/13288517.html
Copyright © 2011-2022 走看看