简体   繁体   English

通过索引链接列表python交换变量?

[英]Swapping variables by indices Linked List python?

I'm learning about LinkedLists, and I've seen a related answer - but I don't think it helps me in my specific situation: Swapping pairs in a linked list in Python, one link disappears?我正在学习 LinkedLists,并且我已经看到了一个相关的答案 - 但我认为它在我的特定情况下我没有帮助: 在 Python 中的链表中交换对,一个链接消失了?

However, I am experiencing a similar problem where one of my variables disappears但是,我遇到了类似的问题,其中一个变量消失了


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

    def get_data(self):
        return self.val

    def set_data(self,val):
        self.val = val

    def get_next(self):
        return self.next

    def set_next(self,next):
        self.next = next


class LinkedList(object):        

    def __init__(self,*values):
        self.count = len(values) -1
        self.head = Node(values[0])
        node = self.head
        for idx, val in enumerate(values):
            if idx == 0:
                continue
            else:
                tempnode = Node(val)
                node.set_next(tempnode)
                node = node.get_next()


    def get_count(self):
        return self.head

    def insert(self,data):
        new_node = Node(data)
        new_node.set_next(self.head)
        self.head = new_node
        self.count +=1

    def insert_at(self,idx,val):
        assert idx <= self.count +1

        if idx == 0:
            self.insert(val)
        else:
            tempIdx = 0
            node = self.head
            while tempIdx < idx -1:
                node = node.get_next()
                tempIdx += 1
            continuation = node.get_next()
            insertion = Node(val)
            node.set_next(insertion)
            node.get_next().set_next(continuation)

    def find(self,val):
        item = self.head
        while item != None:
            if item.get_data() == val:
                return item
            else:
                item = item.get_next()

        return None

    def deleteAt(self,idx):
        if idx > self.count-1:
            return
        if idx == 0:
            self.head = self.head.get_next()
        else:
            tempIdx = 0
            node = self.head
            while tempIdx < idx -1:
                node = node.get_next()
                tempIdx +=1
            node.set_next(node.get_next().get_next())
            self.count -= 1

    def dump_list(self):
        tempnode = self.head
        while (tempnode != None):
            print("Node: ",tempnode.get_data())
            tempnode = tempnode.get_next()

    def swap(self,idx_1,idx_2):
        if idx_1 == idx_2:
            pass
        elif idx_1 > idx_2:
            idx_b,idx_a = idx_1,idx_2
        else:
            idx_b,idx_a = idx_2,idx_1

        tempIdx = 0
        prev_node = None
        node = self.head
        while tempIdx < idx_a - 1:
#             print('while_a')
            prev_node = node
            node = node.get_next()
            tempIdx += 1

        try:
            prev_a = prev_node
            print('prev_a assigned')
        except:
            pass
        elem_a = node
        next_a = node.get_next()
        while tempIdx < idx_b -1:
#             print('while_b')            
            prev_node = node            
            node = node.get_next()
            tempIdx += 1
        prev_b = prev_node            
        elem_b = node
        try:
            next_b = node.get_next()
            print('next_b assigned')            
        except:
            pass

        try:
            prev_a.set_next(elem_b)
            print('prev_a.next assigned elem_b')            
        except:
            pass

        elem_b.set_next(next_a)
        prev_b.set_next(elem_a)
        try:
            elem_a.set_next(next_b)
            print('elem_a.next assigned next_b')            
        except:
            pass


Skip down to the class method, swap.跳到类方法,交换。 This where the problem occurs, and here is my code output, when I call dum_list:这是出现问题的地方,这是我调用 dum_list 时的代码输出:


test = LinkedList(1,2,4)
test.insert_at(idx=2,val=3)
test.dump_list()
>>>> 
Node:  1
Node:  2
Node:  3
Node:  4

## so far, so good!

test.swap(1,2)
test.dump_list()
>>>>
Node:  1
Node:  3
Node:  4

So the node with value 2 is deleted.因此删除值为 2 的节点。 And I'm not sure where I'm going wrong... In the related question, it's the head that needs updating.而且我不确定我哪里出错了......在相关问题中,需要更新的是头部。 But that's not my issue as node of value 2 isn't the head.但这不是我的问题,因为值 2 的节点不是头部。

I took some constructive criticism and changed the swap method quite a bit;我接受了一些建设性的批评,并对交换方法进行了相当多的更改; it works now!它现在有效!


    def swap(self,idx_a,idx_b):
        if idx_a == idx_b:
            return
        elif idx_a > idx_b:
            idx_2,idx_1 = idx_a,idx_b
        else:
            idx_2,idx_1 = idx_b,idx_a

        node = self.head
        tempIdx = 0

        while tempIdx < idx_2:
            if tempIdx != idx_1:
                node = node.get_next()
                tempIdx += 1
            else:
                elem_1 = node.get_data()
                node = node.get_next()
                tempIdx += 1
        elem_2 = node.get_data()

        self.deleteAt(idx_1)
        self.deleteAt(idx_2-1)
        self.insert_at(idx_1,elem_2)
        self.insert_at(idx_2,elem_1)

Look at your swap code;查看您的交换代码; it doesn't handle the case of a an b being near one another: it blithely assumes that your six place-pointers ( prev|elem|next _ a|b ) are independent.它不处理ab彼此靠近的情况:它轻松地假设您的六个位置指针( prev|elem|next _ a|b )是独立的。 Walk through the logic with paper & pencil on your actual case.用纸和铅笔在您的实际案例中了解逻辑。 After painfully locating your two chosen elements, you have在痛苦地定位你选择的两个元素之后,你有

prev_a         => None
elem_a, prev_b => 1
next_a, elem_b => 2
        next_b => 3

Now for your swapping code:现在为您的交换代码:

    prev_a.set_next(elem_b)

This fails silently, and prev_a is None ;这无声地失败,并且prev_aNone good so far目前很好

    elem_b.set_next(next_a)

Node2.next now points back to Node2 itself Node2.next现在指向 Node2 本身

    prev_b.set_next(elem_a)

Node1.next now points back to Node1 itself. Node1.next现在指向 Node1 本身。

    elem_a.set_next(next_b)

Node1.next now points to Node3. Node1.next现在指向 Node3。

Also, note that head still points to Node1, not Node2.另外,请注意head仍然指向 Node1,而不是 Node2。

You have neatly unlinked Node2 from the list;您已经从列表中巧妙地取消了 Node2 的链接; you now have你现在有

head => Node1 => Node3 => Node4 => None
Node2 => Node2

Walk through this case carefully with pencil and paper.用铅笔和纸仔细检查这个案例。 What order of changes will let you swap adjacent nodes?什么顺序的变化会让你交换相邻的节点? The problem here is that you need Node2.next to refer to Node1, rather than the original Node1.next.这里的问题是您需要 Node2.next 来引用 Node1,而不是原始的 Node1.next。

When I took data structures, we carefully checked locations and adjusted pointers from the end of the new list, back to the start.当我获取数据结构时,我们仔细检查了位置并调整了从新列表末尾到开头的指针。 In this case, we would first alter Node1.next .在这种情况下,我们将首先更改Node1.next

Note that you can do also do this by deleting one node and reinserting it on the other side.请注意,您也可以通过删除一个节点并将其重新插入另一侧来执行此操作。


I know this isn't a complete solution;我知道这不是一个完整的解决方案; I hope it's enough to let you finish the repair yourself.我希望这足以让你自己完成修理。 :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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