简体   繁体   中英

python Linked List move backwards and move forward

How can reorder the list so that it starts with the first occurrence of the smallest element and repeatively moves backwards by one step and forward by three steps? I can only find the smallest element (for example ,I got 5 in the following test)? So how can I get the list (5, 53, 65, 33, 51, 62, 61, 38, 74, 45, 97, 49)?

class ExtendedLinkedList(LinkedList):

    def __init__(self, L = None):
        super().__init__(L)

    def rearrange(self):
        node = self.head
        if not node:
            return None
        Min = node.value
        while node:
            if node.value < Min:
                Min = node.value
            node = node.next_node
        return Min


---------test---------

LLL = ExtendedLinkedList([49, 97, 53, 5, 33, 65, 62, 51, 38, 61, 45, 74])

LLL.print()

print(LLL.rearrange())

So you're doing better than what I assume is your fellow student . You have the minimum part worked out. But now here's the question: are you using a doubly-linked list (the sane way to do this) or a singly-linked list (the fun way)? And do you want to give a sane answer, or a fun answer?

The difficulty abarnert is mentioning is that in order to find the minimum value, you have to go through the entire list and keep track of the value , but in order to then start from there in gathering values, you'll need to keep track of the node itself, because otherwise, when you get to the end of the list, you'll know what the minimum value was, but you'll have no way of getting back there! There are a few options here. One is that you can store both the min value and min node when going through. The other is that you can store just the node, and compare values of nodes.

Now, having done that, you'll have the minimum node to start from.

The sane choice : you have a doubly linked list. Each node has a next_node that points to the next node, and a previous_node that points to the previous one. Going back and forward is easy, and I don't think it needs much explanation.

The fun choice : you have a singly linked list. You must always move forward! But that's alright, if you make some slight changes. When finding the minimum, instead of finding the minimum node, find the node before it; let's call it A. Now start making your rearranged list. Do it by first putting on the value of the node after A, then putting the value of A. Now move forward two . Add the value of the node after that, then add that node. And so on... In this way you never actually have to move backward.


In writing this I did not notice the 97,49 at the end of your example. Do you need to loop around too? That can also be done in both cases. You can just set the last node's next_node to the first node after the minimum finding part, and then when reordering, check to make sure you haven't gotten all the way back around.


So playing around with this, I managed to get the following rather compact code to work (I use nn instead of next_node and v instead of value ):

def reorder(f):
    n,a=f,f
    while n.nn:
        a,n=[a,n][n.nn.v<a.nn.v],n.nn
    n.nn,ff=f,a.nn
    while a:
        a.nn.nn,a.nn,a=[(a,None,None),(a,a.nn.nn.nn,a.nn.nn)][
            (a.nn==ff)or((a.nn.nn!=ff.nn)and(a.nn.nn.nn!=ff.nn))]
    return ff

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM