开发者

Python copy and concatenate linked lists, preserve order

I have a basic linked-list implementation in python. Each Cell has some data associated with it and a next object, used to include 开发者_运维百科the rest of the linked list (and null if only the first param of data is given in the constructor).

I want to copy and concatenate two lists together, so that the final product preserves the order and is independent of the two original lists.

Here is what I have:

def list_concat_copy(A, B):
        C = Cell(A)
        while A.next != None:
                A = A.next
                C = Cell(A,C)
        C = Cell(B,C)
        while B.next != None:
                B = B.next
                C = Cell(B,C)
        return C

The issue that I am having is that this reverses the order:

A = Cell(8,Cell(9,Cell(10)))
B = Cell(11,Cell(12,Cell(13)))
C = list_concat_copy(A,B)

Now if I walk_and_print(C) I get 13 12 11 10 9 8

Any thoughts?


You do some weird stuff:

A = Cell(8,Cell(9,Cell(10)))

suggests that your Cell is something like

class Cell(object):
    def __init__(self, val, nxt=None):
        self.val = val
        self.next = nxt

but doing

C = Cell(A)

never copies anything, it just creates a new Cell with the same A as a value.

So, lets start with a Cell that can actually copy itself:

class Cell(object):
    def __init__(self, val, nxt=None):
        self.val = val
        self.next = nxt

    def copy(self):
        if self.next is None:
            return Cell(self.value)
        else:
            return Cell(self.value, self.next.copy())

Now your concat is easy:

def concat_copy(a, b):
        new = a.copy()

        # find the end of the copy
        last = new
        while last.next is not None:
            last = last.next
        # append a copy of the other list
        last.next = b.copy()

For completeness, here is what your tried to do:

def copy( cells ):
    new = Cell(cells.value)
    current = new
    old = cells

    while old.next is not None:
        # copy the current cell
        ccopy = Cell(old.value)

        # add it
        current.next = ccopy

        # prepare for the next round
        current = ccopy
        old = old.next

    return new

I think this helps to understand how you accidentally reversed your cells: You walked the list forwards but the C = Cell(A,C) puts a new Cell before the old C, so that builds the new list from the end.


The lists print out backwards because as you are packing the OUTER elements into the new list FIRST. As you continue to unwrap A, you add a wrapping to C.

The cleanest way to duplicate these lists might be to do a deepcopy of A and B (we'll call them C and D), and then set the deepest element in C (found by traversing until C.next==None) to reference D.


I feel it's a bit difficult to answer this question without seeing the definition of Cell -- but I think I see the mistake. Think of the list as a set of layers. The loop is starting with the innermost value of C. Every time you call Cell in the loop, it "wraps" that value with another Cell with the next value. The outermost Cell has the last value.

In other words,

C = Cell(8)
D = Cell(9, C)
E = Cell(10, D)

is equivalent to

E = Cell(10, Cell(9, Cell(8)))

Is that clear?

EDIT:

For the sake of completeness, here's another way to do it:

class Cell(object):
    def __init__(self, data, n = None):
        self.data = data
        self.next = n

def list_concat_copy(A, B):
        head = Cell(A.data)
        C = head
        while A.next != None:
                A = A.next
                C.next = Cell(A.data)
                C = C.next
        C.next = Cell(B.data)
        C = C.next
        while B.next != None:
                B = B.next
                C.next = Cell(B.data)
                C = C.next
        return head


A = Cell(8, Cell(9, Cell(10)))
B = Cell(11, Cell(12, Cell(13)))
C = list_concat_copy(A, B)


Try this:

def list_concat(x,y):
    if x.next is None:
        return Cell(x.data,y)
    else:
        return Cell(x.data,list_concat(x.next,y))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜