create ListNode from Vec with ref to first Node - rust

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode { next: None, val }
}
}
fn create_list(list : Vec<i32>) -> Option<Box<ListNode>> {
// the code should be written this place
}
i have ListNode struct like this and dont't want to edit this struct and impl. i get a list of i32 number as Vec and i want to create ListNode that each item in list point next item and at the end return first number
for example get vector like this [1,2,3]
and at the end return object like this (i want to create programmatically and this is hand made)
ListNode {
val : 1,
ListNode {
val : 2,
next:ListNode {
next: None,
val : 3
}
}
}
i can't hold first ListNode and return that while dealing with rust borrowing and ownership
-- Update --
i am new to rust. so i create an example from the way i want to solve this problem. this example written in typescript
class ListNode {
val: number
next: ListNode | null
constructor(val?: number, next?: ListNode | null) {
this.val = (val===undefined ? 0 : val)
this.next = (next===undefined ? null : next)
}
toString(): string {
return `ListNode ${this.val}${this.next===null? "" : ' => '+ this.next.toString()}`
}
}
function createList(list : number[]) : ListNode|null {
const firstItem = new ListNode(0,null);
let second = firstItem;
for (let item of list) {
second.next = new ListNode(item,null)
second = second.next;
}
return firstItem.next;
}
const firstNodePointer = createList([1,2,3,4,5])
console.log(firstNodePointer?.toString())

This will create the list in one go.
fn create_list(list : Vec<i32>) -> Option<Box<ListNode>> {
let mut head = None;
let mut current = &mut head;
for x in list {
*current = Some(Box::new(ListNode::new(x)));
current = &mut current.as_mut().unwrap().next;
}
head
}

Related

How to judge whether two Rc point to the same object in Rust?

I get in trouble when trying to write a linked list in rust.
use std::rc::Rc;
#[derive(Debug)]
struct LinkedList<T> {
head: Link<T>,
tail: Link<T>,
}
type Link<T> = Option<Rc<Node<T>>>;
#[derive(Debug)]
struct Node<T> {
elem : T,
next : Link<T>
}
impl <T> LinkedList<T> {
fn new() -> Self {
LinkedList {
head : None,
tail : None
}
}
fn push_front(&mut self, elem: T) {
/* if head is None, take will return None */
let mut a : Option<i32> = None;
assert_eq!(a.take(), None);
let node = Rc::new(Node {
elem,
next : self.head.take(),
});
if self.tail.is_none() {
self.tail = Some(Rc::clone(&node));
}
self.head = Some(node);
}
fn pop_front(&mut self) -> Option<T> {
if self.head.is_none() {
return None;
}
if self.tail.as_ref().unwrap() == self.head.as_ref().unwrap() {}
todo!()
}
}
fn main() {
}
above code is a simple linked list demo.
the important code is the following, and it's buggy apparently:
if self.tail.as_ref().unwrap() == self.head.as_ref().unwrap() {}
I don't know how to judge head and tail whether point to the same object.
There is std::rc::Rc::ptr_eq() for exactly this kind of situation.
Returns true if the two Rcs point to the same allocation in a vein
similar to ptr::eq.

how to perform get_by_idx for linkedlist in Rust

I am programing a LinkedList. Here is My Struct, I need some help on performing a get by index (usize) method.
Here is My Struct Code:
struct Node<T>
where
T: Clone,
{
value: T,
prev: Option<Rc<RefCell<Node<T>>>>,
next: Option<Rc<RefCell<Node<T>>>>,
}
impl<T> Node<T>
where
T: Clone,
{
pub fn new(val: T) -> Self {
Node {
value: val,
prev: None,
next: None,
}
}
}
struct ListNode<T: Clone> {
length: usize,
header: Option<Rc<RefCell<Node<T>>>>,
tail: Option<Rc<RefCell<Node<T>>>>,
}
Now I want to perform a get method to get T by an index:usize, There is a problem
impl<T> ListNode<T>
where
T: Clone,
{
pub fn get(&self, idx: usize) -> Option<T> {
let mut p = &self.header;
for _ in 0..=idx {
if let Some(x) = p {
let clone_p = Rc::clone(x);
// Problem 1 is here, I want p point to the next
p = &((*clone_p).borrow().next);
} else {
return None;
}
}
if let Some(x) = p {
let clone_p = Rc::clone(x);
return Some((*clone_p).borrow().value.clone());
}
None
}
}
How to fix this?
I think I have to clone the ReCell, Here is the code, any optimization?
pub fn get(&self, idx: usize) -> Option<T> {
if let Some(p) = &self.header {
let mut ptr: Option<Rc<RefCell<Node<T>>>> = None;
for _ in 0..=idx {
let v = Rc::clone(p);
let next = &(*v).borrow().next;
if let Some(x) = next {
ptr = Some(Rc::clone(x));
} else {
return None;
}
}
if let Some(x) = ptr {
return Some((*x).borrow().value.clone());
}
}
None
}

How do I handle/circumvent "Cannot assign to ... which is behind a & reference" in Rust?

I'd implementing a simple linked list. This is the (working) code I had so far:
pub struct LinkedList<T> {
start: Option<Box<Link<T>>>,
}
impl<T> LinkedList<T> {
pub fn new() -> LinkedList<T> {
return LinkedList { start: None };
}
}
struct Link<T> {
value: Box<T>,
next: Option<Box<Link<T>>>,
}
impl<T> Link<T> {
fn new_end(value: T) -> Link<T> {
return Link::new(value, None);
}
fn new(value: T, next: Option<Box<Link<T>>>) -> Link<T> {
return Link {
value: Box::new(value),
next,
};
}
}
Next on the list is a method to append to the list; this is what I came up with:
pub fn append(&mut self, element: T) {
// Create the link to append
let new_link = Some(Box::new(Link::new_end(element)));
// Find the last element of the list. None, if the list is empty
let mut last = &self.start;
while let Some(link) = last {
last = &link.next;
}
// Insert the new link at the correct position
match last {
None => self.start = new_link,
Some(last) => last.next = new_link, // This fails
}
}
The precise compiler error is
error[E0594]: cannot assign to `last.next` which is behind a `&` reference
I vaguely get the problem; you cannot mutate an immutable reference. But making the references mutable does seem to make the errors even worse.
How does one handle these kinds of errors? Is there a simple quick-fix, or do you structure your code completely different in Rust?
Your code almost worked. It will if you bind mutably:
impl<T> LinkedList<T> {
pub fn append(&mut self, element: T) {
// Create the link to append
let new_link = Some(Box::new(Link::new_end(element)));
// Find the last element of the list. None, if the list is empty
let mut last = &mut self.start;
while let Some(link) = last {
last = &mut link.next;
}
// Insert the new link at the correct position
match last {
None => self.start = new_link,
Some(ref mut last) => last.next = new_link,
}
}
}
FYI, the answer to this recent question is very good at clarifying the matter about mutability, type and binding in Rust.

How to copy a raw pointer when implementing a linked list in Rust?

I am writing a recursive type ListNode in Rust. I have to use Box in the struct and I am trying to write a loop to add next ListNode. However, I would like to try using a pointer except recursive method.
#[derive(Debug)]
struct ListNode {
val: i32,
next: Option<Box<ListNode>>,
}
impl ListNode {
fn new(i: i32) -> Self {
ListNode { val: i, next: None }
}
fn add_l(&mut self, l: &Vec<i32>) {
let mut p: *mut ListNode = self as *mut ListNode;
for i in l {
unsafe {
(*p).next = Some(Box::new(ListNode::new(*i)));
let temp_b = Box::from_raw(p);
p = Box::into_raw(temp_b.next.wrap());
};
}
}
}
fn main() {
let mut a = ListNode::new(1);
a.add_l(&vec![2, 3, 4, 5]);
println!("{:?}", a);
}
I found that a is changed to the last NodeList with the val of 5:
ListNode { val: 5, next: None }
Is there any way I can copy a pointer so I can keep a stable?
If there is no way I can copy pointer, how can I implement this?
First things first: using unsafe here is completely unnecessary and I would say actively malicious if I saw it in any real code. Don't use unsafe for "fun".
Here's a completely safe implementation of the function which walks backwards to construct the new tail of the list to add:
fn add_l(&mut self, l: &[i32]) {
let mut tail = None;
for &val in l.iter().rev() {
let next = tail.take();
tail = Some(Box::new(ListNode { val, next }));
}
self.next = tail;
}
And one that goes forwards, but requires an unwrap:
fn add_l(&mut self, l: &[i32]) {
let mut head = self;
for &val in l {
head.next = Some(Box::new(ListNode::new(val)));
head = { head }.next.as_mut().unwrap();
}
}
If you had to do it in the forwards direction and had to avoid the unwrap, then maybe you could use unsafe. Every single unsafe block should contain a wealth of comments explaining how the code is safe and doesn't break the guarantees that you need to uphold.
fn add_l(&mut self, l: &[i32]) {
let mut head = self;
for &val in l {
unsafe {
// Boxing a value gives it a stable address.
let mut node = Box::new(ListNode::new(val));
// So long as this raw pointer doesn't escape this block,
// we don't need to worry about its lifetime as it should
// outlive what we need.
let node_raw = &mut node as &mut ListNode as *mut ListNode;
head.next = Some(node);
// Now that we've moved the `Box` into its final place,
// we throw away the reference to head to avoid mutable
// aliasing
head = &mut *node_raw;
}
}
}
See also:
Why is it discouraged to accept a reference to a String (&String), Vec (&Vec) or Box (&Box) as a function argument?
Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time
You have a number of issues here, none of which relate to copying a pointer.
I see what you're trying to do, but you're seeing 'undefined behavior' in action, not a failure to copy the pointer value.
First of all, this:
temp_b.next.unwrap()
Unwrap does not leave the object behind; it consumes it. Every iteration through, you will be setting the value of next to nothing as you call unwrap.
Secondly, on the first iteration through your loop, you convert the original pointer into a box:
let mut p: *mut ListNode = self as *mut ListNode;
// ... p is not reassigned before calling the next statement
Box::from_raw(p);
As a result, you're dropping (free'ing) the root object a when you consume temp_b.
This won't immediately trigger a crash, but it means you've now effectively corrupted the stack. Everything past this point is undefined behavior.
Look at the output when you trace your actual pointer values:
#[derive(Debug)]
struct ListNode {
val: String,
next: Option<Box<ListNode>>,
}
impl ListNode {
fn new(i: &str) -> Self {
ListNode { val: format!("{:?}", i), next: None }
}
fn add_l(&mut self, l: &Vec<&str>) {
let mut p: *mut ListNode = self as *mut ListNode;
println!("self -> {:?}", self as *mut ListNode);
for i in l {
unsafe {
(*p).next = Some(Box::new(ListNode::new(*i)));
let temp_b = Box::from_raw(p);
println!("{:?} -> {:?}", p, temp_b);
p = Box::into_raw(temp_b.next.unwrap());
println!("next p -> {:?}", p);
};
}
println!("self -> {:?}", self as *mut ListNode);
}
}
fn main() {
let mut a = ListNode::new("1");
a.add_l(&vec!["2", "3", "4", "5"]);
println!("self -> {:?}", &mut a as *mut ListNode);
println!("{:?}", a);
}
...
self -> 0x7ffdc10a90f0
0x7ffdc10a90f0 -> ListNode { val: "\"1\"", next: Some(ListNode { val: "\"2\"", next: None }) }
next p -> 0x7fdde801f060
0x7fdde801f060 -> ListNode { val: "\"2\"", next: Some(ListNode { val: "\"3\"", next: None }) }
next p -> 0x7ffdc10a90f0
0x7ffdc10a90f0 -> ListNode { val: "\"3\"", next: Some(ListNode { val: "\"4\"", next: None }) }
next p -> 0x7fdde801f060
0x7fdde801f060 -> ListNode { val: "\"4\"", next: Some(ListNode { val: "\"5\"", next: None }) }
next p -> 0x7ffdc10a90f0 <---- Whhhaaaat! You've been reallocated!
self -> 0x7ffdc10a90f0
self -> 0x7ffdc10a90f0
ListNode { val: "\"5\"", next: None }
So... this is why using unsafe is unsafe.
You can't do what you want to do without using raw pointers all the way; I recommend you look at Rc for what you're trying to do.

What am I doing wrong in this code to implement a `dequeue` function for a queue?

I'm trying to implement a dequeue function for a queue but I am confused how the borrow checker works. What am I doing wrong in this code?
use std::cell::RefCell;
use std::rc::Rc;
use std::mem::replace;
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
struct Node<T>{
item: T,
next: Link<T>
}
pub struct Queue<T>{
first: Link<T>,
last: Link<T>,
length: usize
}
impl<T> Queue<T>{
pub fn new() -> Queue<T> {
Queue {
first: None,
last: None,
length: 0
}
}
pub fn is_empty(&self) -> bool {
self.length == 0
}
pub fn size(&self) -> usize {
self.length
}
pub fn enqueue(&mut self, item: T) {
let temp = self.last.take();
self.last = Some(Rc::new(RefCell::new(Node{
item,
next: None
})));
if self.is_empty() {
self.first = self.last.clone();
} else {
let temp = temp.unwrap();
temp.borrow_mut().next = self.last.clone();
}
self.length += 1;
}
pub fn dequeue(&mut self) -> Result<T, String>{
if let Some(ref mut value) = self.first.take() {
let mut temp = *(value.borrow_mut());
let next = *(temp.next.unwrap().borrow_mut());
let old_value = replace(&mut temp, next);
return Ok(old_value.item);
}
Err("Queue is empty".to_owned())
}
}
Having obtained a mutable reference to the value inside Some, I want to replace with the node that is being referenced by the next field of the node. Do I need to take ownership of the value inside Some? Can I even do that?
Here is an implementation of the dequeue:
pub fn dequeue(&mut self) -> Result<T, String> {
// First, disconnect `self.last` from the element it is pointing,
// since it will have to be updated anyway. If there is no elemen in the
// queue, we're done.
let first = try!(self.first.take().ok_or("Queue is empty".to_owned()));
// if there are two Rc's pointing to this node, then this must be the
// only node, so `self.last` has to go
if Rc::strong_count(&first) == 2 {
self.last = None;
}
let first_node = Rc::try_unwrap(first).ok().expect(
"This should be the only owner of the node"
).into_inner();
self.first = first_node.next;
self.length -= 1;
Ok(first_node.item)
}
Here is the complete code. I also added a dequeue_back for making this almost a double ended queue and some tests.

Resources