简体   繁体   English

如何将链表的最后一个元素移动到 python 中的第一个元素(下面的代码)?

[英]How to move last element of a linked list to first in python (below code)?

#DSA-Prac-1
class Node:
    def __init__(self,data):
        self.__data=data
        self.__next=None

    def get_data(self):
        return self.__data

    def set_data(self,data):
        self.__data=data

    def get_next(self):
        return self.__next

    def set_next(self,next_node):
        self.__next=next_node


class LinkedList:    
    def __init__(self):
        self.__head=None
        self.__tail=None

    def get_head(self):
        return self.__head

    def get_tail(self):
        return self.__tail


    def add(self,data):
        new_node=Node(data)
        if(self.__head is None):
            self.__head=self.__tail=new_node
        else:
            self.__tail.set_next(new_node) 
            self.__tail=new_node

    def insert(self,data,data_before):
        new_node=Node(data)
        if(data_before==None):
            new_node.set_next(self.__head)
            self.__head=new_node
            if(new_node.get_next()==None):
                self.__tail=new_node

        else:
            node_before=self.find_node(data_before)
            if(node_before is not None):
                new_node.set_next(node_before.get_next()) 
                node_before.set_next(new_node)   
                if(new_node.get_next() is None):       
                    self.__tail=new_node
            else:
                print(data_before,"is not present in the Linked list")

    def display(self):
        temp=self.__head
        while(temp is not None):
            print(temp.get_data())
            temp=temp.get_next()     


    def find_node(self,data):
        temp=self.__head
        while(temp is not None):
            if(temp.get_data()==data):
                return temp
            temp=temp.get_next()    
        return None

    def delete(self,data):
        node=self.find_node(data)
        if(node is not None):
            if(node==self.__head):
                if(self.__head==self.__tail):
                    self.__tail=None
                self.__head=node.get_next()
            else:
                temp=self.__head
                while(temp is not None):
                    if(temp.get_next()==node): 
                        temp.set_next(node.get_next())    
                        if(node==self.__tail):
                            self.__tail=temp
                        node.set_next(None)
                        break
                    temp=temp.get_next()    
        else:
            print(data,"is not present in Linked list")


def change_order(input_list):
    'I need the code to be written here'

    return input_list



input_list=LinkedList()
input_list.add(9)
input_list.add(3)
input_list.add(56)
input_list.add(6)
input_list.add(2)
input_list.add(7)
input_list.add(4)

result=change_order(input_list)
result.display()

Only the function change_order must be written.只有 function change_order必须写入。 No changes should be made in other parts of the program .不应对程序的其他部分进行任何更改 The input linked list is 9->3->56->6->2->7->4 and the output should be 4->9->3->56->6->2->7.I need answer for this particular code.输入链表是9->3->56->6->2->7->4,output应该是4->9->3->56->6->2->7.I需要这个特定代码的答案。
This is what i have tried.这是我尝试过的。 Since the head of linkedlist class is a private attribute, i face difficulty in assigning the new head.由于链表 class 的头是私有属性,我在分配新头时遇到困难。

def change_order(input_list):
    temp=input_list.get_head()
    while temp and temp.get_next():
        sec_last = temp
        temp=temp.get_next()     
    sec_last.set_next(None)
    temp.set_next(input_list.get_head())

Your LinkedList class should already provide all the functionality you need to be able to accomplish this without any need to mess around with the pointers yourself:您的 LinkedList class应该已经提供了完成此操作所需的所有功能,而无需自己弄乱指针:

data = input_list.get_tail().get_data()  # get last element
input_list.delete(data)                  # remove last element
input_list.insert(data, None)            # insert that element first

Note that the list interface assumes that all items in the list are unique;请注意,列表界面假定列表中的所有项目都是唯一的; some of these methods don't work properly if you have duplicates and will only ever operate on the first match.如果您有重复项,其中一些方法将无法正常工作,并且只会在第一个匹配项上运行。 If you do the insert before the delete, for example, the delete will remove the item at the head that you just inserted, not the item at the tail that you wanted to remove.例如,如果您在删除之前进行插入,则删除将删除您刚刚插入的头部项目,而不是您要删除的尾部项目。

This is essentially a bug/constraint of this list implementation;这本质上是这个列表实现的一个错误/约束; normally a list interface would provide you with some sort of iterator to allow you to handle cases with multiple matches.通常,列表接口会为您提供某种迭代器,以允许您处理具有多个匹配项的情况。

If you had to work around that under the parameters of the assignment, being able to modify the head isn't the hard part (because you can do that reliably via insert ), but rather popping off the tail (since the only interface that lets you do that is delete , which will flatly not let you access a node by reference, and is therefore always going to do the wrong thing if you're trying to use it to delete the tail when there's a duplicate).如果您必须在分配的参数下解决这个问题,那么能够修改head并不是困难的部分(因为您可以通过insert可靠地做到这一点),而是弹出tail (因为唯一允许你这样做是delete ,它绝对不会让你通过引用访问节点,因此如果你试图使用它来删除重复的尾部,总是会做错事)。 The simplest solution IMO is to just convert the entire list into a better format, do whatever you need, and then convert it back. IMO 最简单的解决方案是将整个列表转换为更好的格式,做任何你需要的事情,然后再转换回来。 (This is a terrible lesson if the goal is to learn how linked lists work, but it's a good lesson if the goal is learn how sometimes you need to do silly things to work around someone else's incompetence.) (如果目标是了解链表是如何工作的,这是一个糟糕的教训,但如果目标是了解有时你需要如何做一些愚蠢的事情来解决别人的无能,这就是一个很好的教训。)

def change_order(input_list):
    'I need the code to be written here'
    # Define helper functions to convert LinkedList to and from List.
    def convert_linked_list_to_list(linked_list):
        """Converts a LinkedList to a native List."""
        arr = []
        node = input_list.get_head()
        while node is not None:
            arr.append(node.get_data())
            node = node.get_next()     
        return arr   

    def rebuild_linked_list_from_list(linked_list, arr):
        """Replaces input LinkedList contents with native List contents."""
        while linked_list.get_head() is not None:
            linked_list.delete(linked_list.get_head().get_data())
        for data in arr:
            linked_list.add(data)

    # Now do the order change using a List.
    arr = convert_linked_list_to_list(input_list)
    rebuild_linked_list_from_list(input_list, arr[-1:] + arr[:-1])
    return input_list

In real life, you'd define these helpers outside of this function, because they're bound to be useful in other situations where you need to manipulate one of these LinkedList containers in ways that its terrible interface doesn't support, but the parameters of the assignment require everything to be contained to change_order , so there you have it.在现实生活中,您将在此 function 之外定义这些助手,因为它们在您需要以糟糕的界面不支持的方式操作这些LinkedList容器之一的其他情况下一定很有用,但参数分配要求所有内容都包含在change_order中,所以你有它。

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

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