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


    双向链表类:

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

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

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

      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()
  • 相关阅读:
    如何分析matlab程序的主要效率问题
    matlab的二维卷积操作
    移动,联通,电信手机都属于什么频段?
    开始学习Python
    利用R进行多元线性回归分析
    PANGU---Planet and Asteroid Natural scene Generation Utility
    中兴N909手机关闭照相机声音
    0709 C语言常见误区----------函数指针问题
    0709 C语言常见误区----------二维数组做参数
    0707 父子进程之间传递文件描述符
  • 原文地址:https://www.cnblogs.com/BBS2013/p/13288517.html
Copyright © 2020-2023  润新知