【问题标题】:Swapping variables by indices Linked List python?通过索引链接列表python交换变量?
【发布时间】:2020-02-04 20:00:43
【问题描述】:

我正在学习 LinkedLists,并且我已经看到了相关的答案 - 但我认为它在我的具体情况下对我没有帮助:Swapping pairs in a linked list in Python, one link 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


跳到类方法,交换。这是问题发生的地方,这是我调用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

因此删除值为 2 的节点。而且我不确定我哪里出错了......在相关问题中,需要更新的是头部。但这不是我的问题,因为值为 2 的节点不是头部。

我接受了一些建设性的批评,并对交换方法进行了相当大的改变;现在可以了!


    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)

【问题讨论】:

  • 不相关:if idx_1 == idx_2: pass 仍将尝试运行该方法的其余部分,而无需设置 idx_aidx_b。鉴于这种情况可能是一个问题,您可能希望将pass 更改为return。此外,except:pass 的所有使用都是以令人困惑的方式行为不端的机会; 从不对任何情况都使用 base except:,除非你想记录并重新raise 异常,并且永远不要捕获任何异常,除非你知道什么会导致它并且有一个有用的方法来处理它它;默默地忽略它并试图继续前进是所有可能世界中最糟糕的。
  • 变量和函数名称应遵循lower_case_with_underscores 样式。您不需要这些简单的 getter 和 setter,这不是 Java。此外,assert 应仅用于调试,而不应在程序正常执行期间使用。

标签: python linked-list


【解决方案1】:

查看您的交换代码;它不处理 ab 彼此靠近的情况:它愉快地假设您的六个位置指针( prev|elem|next _ a|b )是独立的。用纸和铅笔在你的实际案例上演练逻辑。在痛苦地找到你选择的两个元素之后,你有

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

现在是你的交换代码:

    prev_a.set_next(elem_b)

这会静默失败,prev_aNone;到目前为止还不错

    elem_b.set_next(next_a)

Node2.next 现在指向 Node2 本身

    prev_b.set_next(elem_a)

Node1.next 现在指向 Node1 本身。

    elem_a.set_next(next_b)

Node1.next 现在指向 Node3。

另外,请注意head 仍然指向 Node1,而不是 Node2。

您已经从列表中巧妙地取消了 Node2 的链接;你现在有

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

用铅笔和纸仔细检查这个案例。什么样的更改顺序可以让您交换相邻节点?这里的问题是你需要 Node2.next 来引用 Node1,而不是原来的 Node1.next。

当我采用数据结构时,我们仔细检查了位置并调整了从 new 列表末尾到开头的指针。在这种情况下,我们将首先更改Node1.next

请注意,您也可以通过删除一个节点并将其重新插入另一侧来执行此操作。


我知道这不是一个完整的解决方案;我希望这足以让您自己完成修复。 :-)

【讨论】:

  • 谢谢!我不会把 DS&A 当作功劳,只是自学。总的来说,我有点不知所措,但你的建议很有帮助:)
  • 当然。如果您再次陷入困境,只需发布​​后续说明以及您纠结的地方。去过那里,做到了,...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 2021-08-15
  • 1970-01-01
  • 2017-03-31
相关资源
最近更新 更多