假设我使用的是非标准的链表类List.h
。这个类正在运行,模板化,并具有添加/删除到前面和添加/删除到后面,isEmpty()等的典型功能。
此列表没有任何begin()和end()功能。此外,链表类必须包含迭代器功能吗?或者,当我创建一个新的List时,我可以自己创建这个东西吗?
我习惯使用STL,所以我通常会使用这段代码:
typedef vector<OBJECT>::iterator QuoteIt;
for(QuoteIt i = deposits.begin(); i != deposits.end(); ++i)
无论如何,我可以说我创建了一个新的“列表”。
List<int>deposits;
甚至是对象列表
List<OBJECT>deposits;
所以让我说我addToBack()
20个不同的整数,这样就可以创建适当的新节点数。
现在,我如何遍历此列表,以便找到所有这些整数的总和?这可能,或者我目前的功能是否可以阻止这种情况?我必须在List类中实现某种迭代器吗?
现在我知道我可以保留一个外部变量,每次我进行addToBack()
调用以跟踪我的总和。但是,我希望代码也与对象列表兼容。 (我希望能够在节点中搜索一个值,并最终在同一节点中检索另一个值)
我已经习惯使用stl::list
并使用迭代器创建for循环,我真的不知道如何使用其他类。
顺便说一句,这是List()
的代码:
template<class NODETYPE>
class List{
public:
List();
~List();
void insertAtFront(const NODETYPE &);
void insertAtBack(const NODETYPE &);
bool removeFromFront( NODETYPE &);
bool removeFromBack( NODETYPE &);
bool isEmpty() const;
private:
ListNode< NODETYPE > *firstPtr; //pointer to first node
ListNode< NODETYPE > *lastPtr;
//Function to allocate a new node
ListNode< NODETYPE > *getNewNode ( const NODETYPE &);
};
//default constructor
template <class NODETYPE>
List< NODETYPE > ::List()
: firstPtr(0),
lastPtr(0)
{
cout<<"Creating Nodes! \n\n!"<<endl;
}
//deconstructor
template <class NODETYPE>
List<NODETYPE>::~List(){
if(!isEmpty() ){
cout<<"Destroying nodes!"<<endl;
ListNode<NODETYPE> *currentPtr=firstPtr;
ListNode<NODETYPE> *tempPtr;
while( currentPtr !=0){
tempPtr = currentPtr;
currentPtr=currentPtr->nextPtr;
delete tempPtr;
}
}
cout<<"All nodes destroyed! \n\n";
}
template <class NODETYPE>
bool List <NODETYPE>::removeFromFront( NODETYPE & value){
if ( isEmpty() )
return false;
else{
ListNode<NODETYPE> *tempPtr = firstPtr;
if (firstPtr== lastPtr)
firstPtr=lastPtr = 0;
else
firstPtr=firstPtr->nextPtr;
value = tempPtr->data;
delete tempPtr;
return true;
}
}
template <class NODETYPE>
bool List<NODETYPE>::removeFromBack(NODETYPE &value)
{
if (isEmpty())
return false;
else{
ListNode< NODETYPE> *tempPtr = lastPtr;
if( firstPtr == lastPtr)
firstPtr = lastPtr = 0;
else{
ListNode<NODETYPE> *currentPtr=firstPtr;
//Finds second to last element
while(currentPtr->nextPtr !=lastPtr)
currentPtr=currentPtr->nextPtr;
lastPtr = currentPtr;
currentPtr->nextPtr=0;
}
value = tempPtr->data;
delete tempPtr;
return true;
}
}
//Checks to see if list is empty
template< class NODETYPE>
bool List< NODETYPE >::isEmpty() const{
return firstPtr == 0;
}
//returns a pointer to newly created Node
template<class NODETYPE>
ListNode<NODETYPE> *List<NODETYPE>::getNewNode(const NODETYPE &value){
return new ListNode<NODETYPE>(value);
}
答案 0 :(得分:5)
回应:
现在,我如何遍历此列表,以便找到所有这些整数的总和?这可能,或者我目前的功能是否可以阻止这种情况?我必须在List类中实现某种迭代器吗?
你需要实现一种迭代你的列表的方法(不作为副作用)破坏你的列表。
答案 1 :(得分:3)
回应:
现在,我怎么能遍历这个列表呢? 可以找到所有这些整数的总和?是 那可能,或者是我现在的 功能阻止了吗?我会 必须实施某种 我的List Class的迭代器?
无论你如何设计一个链表,你必须有一些指向列表开头的指针,你必须知道你何时在最后(例如当“next”为null时,或者通过指向结尾的指针)。通过以某种方式公开这些数据,您始终可以设置列表遍历:
firstPtr
。)->nextPtr
。)使用该模式在访问每个元素时累积值,您应该能够轻松处理任务。
如果你的列表没有公开访问它的开头,那么肯定不是通用列表!
答案 2 :(得分:2)
由于没有功能只能获取节点而不从列表中删除它,所以不能简单地创建一个“附加”迭代器而不更改List
类。你需要做的最少的是
ListIterator
班级begin
和end
函数begin
和end
个函数添加到List
类如果没有这三者,你就无法实现自己想要的目标。
答案 3 :(得分:2)
你可以采用多种方式。您可以选择创建自己的迭代器,也可以公开访问列表的头部。
选项1与stl列表兼容,因此您可能希望使用该路由。迭代器本质上是一个ptr,它会覆盖inc和dec运算符,以转到列表中的下一个或上一个位置。
如果你研究了基本的数据结构,你就会知道遍历一个列表是微不足道的。
Node<type> t = head;
while (t != NULL)
{
// process node here
t = t->next;
}
代码可能会有所不同,具体取决于您是否使用虚拟节点。
答案 4 :(得分:1)
您的列表似乎有两种迭代方式(前后)
List<int>deposits;
.. add stuff:
int o;
int sum = 0;
while(deposits.removeFromFront(o)) {
sum+=o;
}
但不好的是,迭代它,你也会破坏列表, 你可以提供List :: firstPtr和ListNode :: nextPtr的公共访问器;在这种情况下你可以这样做:
List<int>deposits;
.. add stuff:
int sum = 0;
for(ListNode<int> *ptr = deposits.firstPtr; ptr ; ptr = ptr->nextPtr)
sum+=ptr->data;
但是,如果可以,请使用现有的STL容器。