将单链表更改为双向链表

时间:2015-03-04 22:15:29

标签: python data-structures singly-linked-list doubly-linked-list

我创建了一个单独链接列表功能,我的教授说要获得额外的功劳,我们可以将其改为双重链接列表。我读了一些东西,比如添加一个prev_node函数,比如这个。

class ListNode(object):

    def __init__(self, item = None, prev = None, link = None):

        '''creates a ListNode with the specified data value and link
        post: creates a ListNode with the specified data value and link'''

        self.item = item
        self.prev = prev
        self.link = link

然而,我很困惑从那里去哪里。我知道我需要像我在这里一样添加尾巴和头部。

from DoublyListNode import ListNode

class LinkedList(object):

    #--------------------------------------------------------------

    def __init__(self, seq=()):

        """ Pre: Creates a Linked List
        Post: Creates a list containing the items in the seq=()"""

        if seq == ():

            # If there is no items to be put into the list, then it creates an empty one.
            self.head = None
            self.tail = None

        else:

            # Creates a node for the first item.
            self.head = ListNode(seq[0], None)

            # If there are remaining items, then they're added while keeping track of the last node.
            last = self.head
            for item in seq[1:]:
                last.link = ListNode(item, None)
                last = last.link

        self.size = len(seq)

有人能告诉我,(不要为我做),为了将我的链表更改为双重链表,我必须做些什么?我知道我现在必须引用尾巴以及头部,但我对如何做到这一点感到非常难过。

2 个答案:

答案 0 :(得分:0)

我不知道Python,但这是在Haskell中实现它的一种方法:

import qualified Data.Vector as V
import Data.Vector (Vector, (!), fromList)

data DLL a = DLL {prevP :: Maybe (DLL a),
                  val :: a,
                  nextP :: Maybe (DLL a)}

list2DLL :: [a]->DLL a
list2DLL = vec2DLL . fromList

prev :: Int -> Maybe Int
prev i | i <= 0 = Nothing
prev i = Just (i-1)

next :: Int -> Int -> Maybe Int
next i lim | i < lim-1 = Just(i+1)
next _ _ = Nothing

vec2DLL :: Vector a -> DLL a
vec2DLL v = scaffold ! 0 where
  scaffold = V.mapWithIndex go v
  go i a = DLL (fmap (scaffold!) $ prev i)
               a
               (fmap (scaffold!) $ next i (length v))

答案 1 :(得分:0)

  

我知道我现在必须引用尾巴以及头部,但我很难知道如何做到这一点。

一个很好的入门方式是用英语写出你想要做的事情:

  

我有一个链接列表,我需要将其转换为双向链表。为此,每个节点都需要跟踪prevnext,我的列表需要headtail节点。创建列表时,headtail应指向同一项目。当我向列表中添加一个新项目时,它应该成为最后一个节点,它的.prev元素应该是前一个.tail,它也应该是该项目的.next项目

一旦您对要做的事情有了描述,那么将其转换为代码应该相对简单。