2017-08-06 4 views
0

私は、キューにdequeue機能を実装しようとしているが、私は借りチェッカーがどのように機能するか混乱しています。このコードで私は間違って何をしていますか?キューの `dequeue`関数を実装するのに、このコードで何が間違っていますか?

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()) 
    } 
} 

はIノードのnextフィールドによって参照されているノードと交換する、Some内の値に変更可能な参照を取得しました。 Someの値の所有権を取得する必要がありますか?それはできますか?ここで

答えて

1

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。私はまたこれをほぼダブルエンドキューといくつかのテストにするためにdequeue_backを追加しました。

+0

ちょっと感謝。デキューも大変だった。 :D – codeNoob

関連する問題