简体   繁体   中英

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. 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.
This is what i have tried. Since the head of linkedlist class is a private attribute, i face difficulty in assigning the new head.

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:

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). The simplest solution IMO is to just convert the entire list into a better format, do whatever you need, and then convert it back. (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.

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