2013-04-15 91 views
1

我一直试图通过调整我的add()和remove()方法,使我的单链表成为双圆形。单链表到循环链表

这里是我的代码:

private LLNode<E> head;  // the first node in the list 
private LLNode<E> tail;  // the last node in the list 

// Adds the specified new item to the back of the list. 
public void add(E newData) 
{ 
    if (head == null) // if the list is empty... 
     addToHead(newData);  
    else  
     addAfter(newData, nodeAt(size - 1)); 
} 

// Removes and returns the item at the specified index of the list. 
public E remove(int index) 
{ 
    if (index == 0)   // if removing from the head... 
     return removeFromHead(); 
    else 
     return removeAfter(nodeAt(index - 1)); 
} 

    private void addToHead(E newItem) 
    { 
     LLNode<E> newNode = new LLNode<E>(); 
     newNode.data = newItem; 
     newNode.next = head;  
     head = newNode; 
     head.prev = tail; 
     tail.next = newNode; 
     size++; 
    } 

// Removes the head node from the list. 
private E removeFromHead() 
{ 
    if (head != null) { 
     E temp = head.data; 
     head = head.next; 
     head.prev = tail; 
     tail.next = head; 
     size--; 
     return temp; 
    } else 
     throw new NoSuchElementException(); 
} 

// Adds a new node containing the specified data, after the 
// specified node in the list. 
private void addAfter(E newItem, LLNode<E> where) 
{ 
    if (where != null) { 
     LLNode<E> newNode = new LLNode<E>(); 
     newNode.data = newItem; 
     newNode.next = where.next; 
     where.next = newNode; 
     newNode.prev = where; 
     size++; 
    } else { 
     throw new NoSuchElementException(); 
    } 
} 

// Removes the node after the specified node in the list. 
private E removeAfter(LLNode<E> where) 
{ 
    if (where != null && where.next != null) { 
     E temp = where.next.data; 
     where.next = where.next.next; 
     where.next.prev = where; 
     size--; 
     return temp; 
    } else 
     throw new NoSuchElementException(); 
} 

在我的主要方法:

TopSpinLinkedList<Integer> ll = new TopSpinLinkedList<Integer>(numTokens, spinSize); 

    //fills LinkedList with tokens 
    for(int i = 1; i <= numTokens; i++) { 
     ll.add(i); 
    } 

当我尝试调用这个方法:

//shifts all elements in LinkedList to left by one 
public void shiftLeft() 
{ 
    if(head == null || head.next == null) 
     return; 
    LLNode<E> temp = new LLNode<E>(); 
    temp = head; 
    head = head.next; 
    temp.next = null; 
    tail.next = temp; 
    tail = temp; 
} 

一个NullPointerException异常运行时显示。我很确定它与我的add()和remove()方法有关。我只是不明白我到底做了什么错误,把它变成一个双向链表。任何帮助将非常感激。

+0

在 “tail.next = newNode;”在addToHead()方法 – GreatBambino

回答

1

在你的addToHead方法中,当你在做tail.next = newNode时,你确定已经初始化了你的tail变量吗?

试试这个:

private void addToHead(E newItem) 
    { 
     LLNode<E> newNode = new LLNode<E>(); 
     newNode.data = newItem; 
     head = newNode; 
     tail = newNode; 
     newNode.prev = newNode.next = newNode; 
     size++; 
    } 
+0

内这完美的工作! tysm! – GreatBambino

0
private void addToHead(E newItem){ 
    LLNode<E> newNode = new LLNode<E>(); 
    newNode.data = newItem; 

    // head and tail are empty 
    head = newNode; 
    tail = newNode; 
    head.next = newNode; 
    tail.next = newNode; 
    head.prev = newNode; 
    tail.prev = newNode; 
} 


private void addAfter(E newItem, LLNode<E> where){ 
    if (where != null) { 
     LLNode<E> newNode = new LLNode<E>(); 
     newNode.data = newItem; 


     //this part is what you need 
     newNode.next = where; 
     newNode.prev = where.prev; 
     where.prev.next = newNode; 
     where.prev = newNode; 
     size++; 
    } else { 
     throw new NoSuchElementException(); 
    } 
} 

//我已经改变了我的代码,这应该现在的工作。 //我将元素where右移一个位置并将newNode插入其位置。

另外,如果您使用的是双向链表,则不需要尾部。你可以简单地摆脱它。

-1

template<class T> 
 
ostream& operator<<(ostream& os, CircularList<T>& ll) 
 
{ 
 
\t if(!(ll.isEmpty())) 
 
\t { 
 
\t \t os<<"["; 
 
\t \t 
 
\t \t int size=ll.size(); 
 
\t \t int counting=0; 
 
\t \t while(counting<size) 
 
\t \t { 
 
\t \t \t os<<ll.get(counting); 
 
\t \t \t if(counting+1<size) 
 
\t \t \t \t os<<","; 
 
\t \t \t counting++; 
 
\t \t } 
 
\t \t os<<"]"; 
 

 
\t } 
 
\t else 
 
\t { 
 
\t \t os<<"[]"; 
 
\t } 
 
} 
 

 
template<class T> \t \t 
 
CircularList<T>::CircularList() 
 
{ 
 
\t this->head = NULL; 
 
} 
 

 
template<class T> 
 
CircularList<T>::CircularList(const CircularList<T>& other) 
 
{ 
 
\t this->head=0; 
 
\t Node<T>* tempHead=other.getLeader(); 
 
\t while(tempHead!=0) 
 
\t { 
 
\t \t Node<T> *temp = new Node<T>(tempHead->data); 
 
\t \t temp->next = 0; 
 
\t \t Node<T>* curr = this->getLeader(); 
 
\t \t if (curr != 0) 
 
\t \t { 
 
\t \t \t while (curr->next != 0) 
 
\t \t \t { 
 
\t \t \t curr = curr->next; 
 
\t \t \t } 
 
\t \t \t curr->next = temp; 
 
\t \t } 
 
\t \t else 
 
\t \t { 
 
\t \t \t this->head = temp; 
 
\t \t } 
 
\t \t tempHead=tempHead->next; 
 
\t } 
 
} 
 

 
template<class T> 
 
CircularList<T>& CircularList<T>::operator=(const CircularList<T>& other) 
 
{ 
 
\t if(&other != this) 
 
\t { 
 
\t \t this->head=0; 
 
\t \t Node<T>* tempHead=other.head; 
 
\t \t while(tempHead!=0) 
 
\t \t { 
 
\t \t \t Node<T>* temp = new Node<T>(tempHead->data); 
 
\t \t \t temp->next = 0; 
 
\t \t \t Node<T>* curr = this->head; 
 
\t \t \t if (curr != 0) 
 
\t \t \t { 
 
\t \t \t \t while (curr->next != 0) 
 
\t \t \t \t { 
 
\t \t \t \t curr = curr->next; 
 
\t \t \t \t } 
 
\t \t \t \t curr->next = temp; 
 
\t \t \t } 
 
\t \t \t else 
 
\t \t \t { 
 
\t \t \t \t this->head = temp; 
 
\t \t \t } 
 
\t \t \t tempHead=tempHead->next; 
 
\t \t } 
 
\t } 
 
    return *this; \t 
 
} 
 

 
template<class T> 
 
CircularList<T>* CircularList<T>::clone() 
 
{ 
 
\t CircularList<T>* circle = new CircularList<T>(*this); 
 
} 
 

 
template<class T> 
 
CircularList<T>::~CircularList() 
 
{ 
 
\t int count =size(); 
 
\t Node<T>* current = this->head; 
 
\t int i=0; 
 
\t while (i<count) 
 
\t { 
 
\t \t Node<T>* next = current->next; 
 
\t \t delete current; 
 
\t \t current = next; 
 
\t \t i++; 
 
\t } 
 
this->head = 0; 
 
} 
 
\t 
 
template<class T> 
 
void CircularList<T>::insert(int index, T data) 
 
{ 
 
\t Node<T> *j= new Node<T>(data); 
 
\t 
 
\t if((0 <= index) &&(index<= size())) 
 
\t { 
 
\t \t if(index==0) 
 
\t \t { 
 
\t \t \t if(isEmpty()) 
 
\t \t \t { 
 
\t \t \t \t this->head=j; 
 
\t \t \t } 
 
\t \t \t else 
 
\t \t \t { 
 
\t \t \t \t Node<T>*skipping=this->head; 
 
\t \t \t \t this->head=j; 
 
\t \t \t \t this->head->next=skipping; \t 
 
\t \t \t } 
 
\t \t } 
 
\t \t else 
 
\t \t { 
 
\t \t \t Node<T> *tempping =this->head; 
 
\t \t \t int counting =1; 
 
\t \t \t while(counting!=index) 
 
\t \t \t { 
 
\t \t \t \t tempping=tempping->next; 
 
\t \t \t \t counting++; 
 
\t \t \t } 
 
\t \t \t j->next=tempping->next; 
 
\t \t \t tempping->next=j; 
 
\t \t } 
 
\t } 
 
\t else 
 
\t { 
 
\t \t throw ("invalid index"); 
 
\t } 
 
} 
 
\t 
 
template<class T> 
 
T CircularList<T>::remove(int index) 
 
{ 
 
\t T pet; 
 
\t if(0 <= index && index<= size()-1) 
 
\t { 
 
\t \t if(!isEmpty()) 
 
\t \t { 
 
\t \t \t Node<T> *ret=getLeader(); 
 
\t \t \t Node<T>* skip=NULL; 
 
\t \t \t if(index!=0) 
 
\t \t \t { 
 
\t \t \t int i=1; 
 
\t \t \t while(i!=(index)) 
 
\t \t \t { 
 
\t \t \t \t ret=ret->next; 
 
\t \t \t \t i++; 
 
\t \t \t } 
 
\t \t \t skip=ret; 
 
\t \t \t pet=get(index); 
 
\t \t \t ret=ret->next; 
 
\t \t \t if(ret->next==NULL) 
 
\t \t \t { 
 
\t \t \t \t delete ret; 
 
\t \t \t \t skip->next=NULL; 
 
\t \t \t \t ret=NULL; 
 
\t \t \t } 
 
\t \t \t else 
 
\t \t \t { 
 
\t \t \t \t skip->next=ret->next; 
 
\t \t \t \t delete ret; 
 
\t \t \t \t ret=NULL; 
 
\t \t \t } 
 
\t \t } 
 
\t \t else 
 
\t \t { 
 
\t \t \t  Node<T> *tmp = this->head->next; 
 
\t \t \t  pet=get(index); 
 
\t \t \t \t delete this->head; 
 
\t \t \t \t this->head = tmp; 
 
\t \t } 
 
\t \t return pet; 
 
\t \t } 
 
\t \t else 
 
\t \t { 
 
\t \t \t throw ("Empty list"); 
 
\t \t } 
 
\t 
 
\t } 
 
\t else 
 
\t { 
 
\t \t throw ("Invalid index"); 
 
\t } 
 
} 
 
\t 
 
template<class T> \t 
 
T CircularList<T>::get(int index) const 
 
{ 
 
\t if(this->head!=NULL) 
 
\t { 
 
\t \t if(0 <= index && index<= size()-1) \t 
 
\t \t { 
 
\t \t \t int counting=0; 
 
\t \t \t Node<T>* p =this->head; 
 
\t \t \t while(p!=NULL) 
 
\t \t \t { 
 
\t \t \t \t if(counting==index) 
 
\t \t \t \t { 
 
\t \t \t \t \t return p->data; 
 
\t \t \t \t } 
 
\t \t \t \t counting++; 
 
\t \t \t \t p=p->next; 
 
\t \t \t } 
 
\t } 
 
\t \t else 
 
\t \t { 
 
\t \t throw ("invalid index"); 
 
\t \t } 
 
\t } \t 
 
\t else 
 
\t { 
 
\t \t throw("empty list"); 
 
\t } 
 
} 
 

 
template<class T> 
 
bool CircularList<T>::isEmpty() 
 
{ 
 
\t if(this->head==0) 
 
\t { 
 
\t \t return true ; 
 
\t } 
 
\t else 
 
\t { 
 
\t \t return false; 
 
\t } 
 
} 
 

 
template<class T> 
 
void CircularList<T>::clear() 
 
{ 
 
\t Node<T>*serp=this->head; 
 
\t while(this->head!=NULL) 
 
\t { 
 
\t \t this->head=this->head->next; 
 
\t \t delete serp; 
 
\t \t serp=this->head; 
 
\t } 
 
} 
 

 
template<class T> 
 
Node<T>* CircularList<T>::getLeader() const 
 
{ 
 
\t return this->head; 
 
} 
 

 
template<class T> 
 
ostream& CircularList<T>::print(ostream& os) 
 
{ 
 
\t os<<*this; 
 
} 
 

 
template<class T> 
 
int CircularList<T>::size() const 
 
{ 
 
\t int counting=0; 
 
\t Node<T> *serp =getLeader(); 
 
\t while(serp!=NULL) 
 
\t { 
 
\t \t serp=serp->next; 
 
\t \t counting++; 
 
\t } 
 
\t return counting; 
 
} 
 

 
template <class T> 
 
CircularList<T>& CircularList<T>::operator+(const CircularList<T>& other) 
 
{ 
 
\t CircularList<T>* serp=new CircularList<T>(*this); 
 
\t Node<T>* hey=other.getLeader(); 
 
\t int counting=serp->size(); 
 
\t int position=0; 
 
\t while(hey!=NULL) 
 
\t { 
 
\t \t serp->insert(counting,other.get(position)); 
 
\t \t hey=hey->next; 
 
\t \t position++; 
 
\t \t counting++; 
 
\t } 
 
\t return *serp; 
 
} 
 
//a friend asked me to help him with some assignment i still have the code

+0

您可能希望为您发现的这些错误提供一些背景知识,以及如何纠正它们。这样我们都可以学习。 – rajah9

+0

问题是Java,你提供了C++代码 – Danh