在C++中遍历非STL链表,可能吗
Traversing a non-STL linked-list in C++, possible?
假设我使用的是一个非标准的链表类List.h
。这个类是正常工作的,模板化的,具有前面添加/删除和后面添加/删除、isEmpty((等典型功能。
此列表没有任何begin((和end((功能。此外,链表类是否必须包含迭代器功能?或者,当我创建一个新列表时,这是我可以自己创建的吗?
我习惯于使用STL,所以我通常会使用以下代码:
typedef vector<OBJECT>::iterator QuoteIt;
for(QuoteIt i = deposits.begin(); i != deposits.end(); ++i)
不管怎样,假设我创建了一个新的"列表"。
List<int>deposits;
甚至对象列表
List<OBJECT>deposits;
假设我addToBack()
是20个不同的整数,这样就创建了适当的#个新节点。
现在,我如何遍历这个列表,以便找到所有这些int的和?这可能吗?或者我目前的功能阻止了这一点吗?我必须为我的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! nn!"<<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! nn";
}
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);
}
响应:
现在,我如何遍历这个列表,以便找到所有这些int的和?这可能吗?或者我目前的功能阻止了这一点吗?我必须为我的List类实现某种迭代器?
您需要实现一种对列表进行迭代的方法,该方法不会(作为副作用(破坏列表。
响应:
现在,我如何遍历这个列表,以便能找到所有这些int的和吗?是可能的,或者我的电流功能阻止了这一点?我会的必须实现某种迭代器到我的列表类?
无论你如何设计链表,你都必须有某种指向列表开头的指针,并且你必须有一种方法来知道你何时处于末尾(例如,"next"何时为空,或者有一个指向末尾的指针(。通过以某种方式公开这些数据,您总是可以设置列表遍历:
- 从头开始。(在您的情况下,请联系
firstPtr
。( - 如果您不在末尾,请移动到下一个元素。(在您的情况下,获取
->nextPtr
。(
使用该模式在访问每个元素时积累价值,您应该能够轻松地处理任务。
如果您的列表不允许您公开访问它的开头,那么它肯定不是一个通用列表!
您可以通过多种方式处理此问题。您可以选择创建自己的迭代器,也可以为列表的头部提供公共访问权限。
选项1与stl列表兼容,因此您可能希望采用该路线。迭代器本质上是一个ptr,它覆盖inc和dec运算符以转到列表中的下一个或上一个位置。
如果你研究了基本的数据结构,你就会知道遍历列表是微不足道的。
Node<type> t = head;
while (t != NULL)
{
// process node here
t = t->next;
}
根据是否使用虚拟节点,代码可能会有所不同。
由于没有在不从列表中删除节点的情况下只获取的功能,因此不能在不更改List
类的情况下简单地创建"附加"迭代器。你至少需要做的是
- 外部
ListIterator
类的好友 - 免好友
begin
和end
功能 - 向
List
类添加begin
和end
函数
如果没有这三者中的任何一个,你就无法实现你想要的。
您的列表似乎有两种迭代方法(向前和向后(
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容器。
- 反向给定链表中的K节点
- 如果没有malloc,链表实现将失败
- 文本文件中的单词链表
- 努力将整数转换为链表。不知道我在这里做错了什么
- 链表,反向函数,数据结构
- 使用std::list创建循环链表
- 链表的泛型函数remove()与成员函数remove)
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 我们可以删除链表中静态内存中的节点吗
- C++ STL 双链表性能比较
- STL 链表::如何访问成员
- 使用 STL 反转递归链表
- 类似STL的列表由带节点的链表组成
- 索引链表(哈希表中的索引)的C++/STL 结构
- 双 STL 链表push_front错误
- STL队列(OR堆栈)的deque和链表(+vector)实现之间有什么区别
- 通过链表迭代插入STL向量值
- 在C++中遍历非STL链表,可能吗
- 使用STL列表容器,需要初始化作为属性的链表
- STL deque是作为循环链表实现的