0
votes

I'm new on Rust, i'm just doing some exercise. There is a linked list. For example, 0->1->2->3->4, cut it off at index 2, then reverse both, and then compose them. => 0<-1<-2 3<-4 => 2->1->0->4->3

#[derive(debug)]
struct Node{
    val: usize,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(i: usize) -> Node {
    ...
    }

    fn reverse_at(self, k: usize) -> Box<Node> {
        let mut prev = None;
        let mut curr = Box::new(self);

        let first_part_tail = &mut curr;

        let mut i: usize = 0;
        while i <= k {
            let next = curr.next.take();
            curr.next = prev;
            match next {
                Some(next_node) => {
                    prev = Some(curr);
                    curr = next_node;
                }
                None => return curr,
            }
            i += 1;
        }

        let head = prev.unwrap();
        prev = None;
        loop {
            let next = curr.next.take();
            curr.next = prev;
            match next {
                Some(next_node) => {
                    prev = Some(curr);
                    curr = next_node;
                }
                None => {
                    first_part_tail.next = Some(curr);
                    return head;
                }
            }
        }
    }
}

I need to get the mutable borrow of the first node0, and set 0.next=4 after getting the last node4 at the end of function. But node0's ownership is already been send to node1. Obviously, error[E0499]: cannot borrow `curr.next` as mutable more than once at a time happens, i don't know what to do. This stuck me for a long time. Any help please.

play.rust-lang.org/...

&, i suppose this function would change the Node itself. And i don't know how to change self reference into the new node, so i used self. If someone can modify this, that helps too. Maybe, change this function to

fn reverse_at(&mut self, k:usize){
    ...
}
1
It might be helpful to include a complete example with main in Rust playground (play.rust-lang.org). I started to take a look and noticed that you are mising & before self in your method signature. see: doc.rust-lang.org/1.30.0/book/2018-edition/…Ultrasaurus
@Ultrasaurus I've add the playground link. &, i suppose this function would change the Node itself. And i don't know how to change self reference into the new node, so i used self. If someone can modify this, that helps too.Icatream
Unrelated to your error, I don't see how your program creates a linked list... see playground example with just "new" play.rust-lang.org/…Ultrasaurus
I found this unofficial rust learning resource that has a lot of linked list examples that might be helpful: rust-unofficial.github.io/too-many-listsUltrasaurus
@Ultrasaurus The struct Node was from something else. Just Node::new(1234), this will create a linked list, 4->3->2->1->None. Node::new(1) will create 1->None. I'll look at the learning resource, thanks.Icatream

1 Answers

0
votes

@Ultrasaurus thanks for the learning resource https://rust-unofficial.github.io/too-many-lists/. Now i solve the problem, although it takes several time.

The final code is here playground

There is a little bit weird, that my LinkedNumber.head is Node, cause the LinkedNumber always has a head, might be zero, but not null. Maybe it should be Box<Node>.

At line 71, i use ptr::read, it will

Reads the value from src without moving it.

mem::take is ok, either. But it needs to initial Node with a default value by trait Default.

Than i use Box::new to move the node from stack into heap. (There's no necessary to do this, if LinkedNumber.head is Box<Node>)

At line 73, mark the raw_pointer *const Node of the head.

At line 94, if the link was break into two, cast *const Node into *mut Node, dereference it, set (*ptr).next with the last node of the original link.

How to test: change the number in num.reverse_at(3) at line 171, it works fine.