STL是C++的支柱之一。它使工作变得更加轻松,尤其是当您专注于解决问题并且不想花时间去实施已经可以保证可靠解决方案的事情时,尤其如此。软件工程的关键方面之一是避免重新发明轮子。可重用性始终是首选。
虽然依赖库函数会直接影响我们的效率,但对库的工作原理没有正确的了解有时会失去我们一直在谈论的工程效率的含义。错误选择的数据结构可能会在将来的某个时候回来困扰我们。解决方案很简单。使用库方法,但要知道它如何在后台处理操作。
说够了!今天,我们将研究如何实现单个链表的自己的Iterator模式。因此,这是链接列表的STL实现的样子:
C++
#include
using namespace std;
int main()
{
// creating a list
vector list;
// elements to be added at the end.
// in the above created list.
list.push_back(1);
list.push_back(2);
list.push_back(3);
// elements of list are retrieved through iterator.
for (vector::iterator it = list.begin();
it != list.end(); ++it)
cout << *it << " ";
return 0;
}
Java
import java.util.*;
class GFG
{
public static void main(String[] args)
{
// creating a list
ArrayList list = new ArrayList<>();
// elements to be added at the end.
// in the above created list.
list.add(1);
list.add(2);
list.add(3);
// elements of list are retrieved through iterator.
Iterator it = list.iterator();
while (it.hasNext())
{
System.out.print(it.next() + " ");
}
}
}
// This code is contributed by pratham76
Python3
if __name__=='__main__':
# Creating a list
list = []
# Elements to be added at the end.
# in the above created list.
list.append(1)
list.append(2)
list.append(3)
# Elements of list are retrieved
# through iterator.
for it in list:
print(it, end = ' ')
# This code is contributed by rutvik_56
C++
// C++ program to implement Custom Linked List and
// iterator pattern.
#include
using namespace std;
// Custom class to handle Linked List operations
// Operations like push_back, push_front, pop_back,
// pop_front, erase, size can be added here
template
class LinkedList
{
// Forward declaration
class Node;
public:
LinkedList() noexcept
{
// caution: static members can't be
// initialized by initializer list
m_spRoot = nullptr;
}
// Forward declaration must be done
// in the same access scope
class Iterator;
// Root of LinkedList wrapped in Iterator type
Iterator begin()
{
return Iterator(m_spRoot);
}
// End of LInkedList wrapped in Iterator type
Iterator end()
{
return Iterator(nullptr);
}
// Adds data to the end of list
void push_back(T data);
void Traverse();
// Iterator class can be used to
// sequentially access nodes of linked list
class Iterator
{
public:
Iterator() noexcept :
m_pCurrentNode (m_spRoot) { }
Iterator(const Node* pNode) noexcept :
m_pCurrentNode (pNode) { }
Iterator& operator=(Node* pNode)
{
this->m_pCurrentNode = pNode;
return *this;
}
// Prefix ++ overload
Iterator& operator++()
{
if (m_pCurrentNode)
m_pCurrentNode = m_pCurrentNode->pNext;
return *this;
}
// Postfix ++ overload
Iterator operator++(int)
{
Iterator iterator = *this;
++*this;
return iterator;
}
bool operator!=(const Iterator& iterator)
{
return m_pCurrentNode != iterator.m_pCurrentNode;
}
int operator*()
{
return m_pCurrentNode->data;
}
private:
const Node* m_pCurrentNode;
};
private:
class Node
{
T data;
Node* pNext;
// LinkedList class methods need
// to access Node information
friend class LinkedList;
};
// Create a new Node
Node* GetNode(T data)
{
Node* pNewNode = new Node;
pNewNode->data = data;
pNewNode->pNext = nullptr;
return pNewNode;
}
// Return by reference so that it can be used in
// left hand side of the assignment expression
Node*& GetRootNode()
{
return m_spRoot;
}
static Node* m_spRoot;
};
template
/*static*/ typename LinkedList::Node* LinkedList::m_spRoot = nullptr;
template
void LinkedList::push_back(T data)
{
Node* pTemp = GetNode(data);
if (!GetRootNode())
{
GetRootNode() = pTemp;
}
else
{
Node* pCrawler = GetRootNode();
while (pCrawler->pNext)
{
pCrawler = pCrawler->pNext;
}
pCrawler->pNext = pTemp;
}
}
template
void LinkedList::Traverse()
{
Node* pCrawler = GetRootNode();
while (pCrawler)
{
cout << pCrawler->data << " ";
pCrawler = pCrawler->pNext;
}
cout << endl;
}
//Driver program
int main()
{
LinkedList list;
// Add few items to the end of LinkedList
list.push_back(1);
list.push_back(2);
list.push_back(3);
cout << "Traversing LinkedList through method" << endl;
list.Traverse();
cout << "Traversing LinkedList through Iterator" << endl;
for ( LinkedList::Iterator iterator = list.begin();
iterator != list.end(); iterator++)
{
cout << *iterator << " ";
}
cout << endl;
return 0;
}
输出
1 2 3
cin和cout的优点之一是它们不需要格式说明符来处理数据类型。结合模板,使代码更清晰易读。尽管我更喜欢C++中的命名方法以大写字母开头,但是此实现遵循STL规则来模拟确切的方法调用集,即push_back,begin,end。
这是我们自己的LinkedList及其Iterator模式的实现:
C++
// C++ program to implement Custom Linked List and
// iterator pattern.
#include
using namespace std;
// Custom class to handle Linked List operations
// Operations like push_back, push_front, pop_back,
// pop_front, erase, size can be added here
template
class LinkedList
{
// Forward declaration
class Node;
public:
LinkedList() noexcept
{
// caution: static members can't be
// initialized by initializer list
m_spRoot = nullptr;
}
// Forward declaration must be done
// in the same access scope
class Iterator;
// Root of LinkedList wrapped in Iterator type
Iterator begin()
{
return Iterator(m_spRoot);
}
// End of LInkedList wrapped in Iterator type
Iterator end()
{
return Iterator(nullptr);
}
// Adds data to the end of list
void push_back(T data);
void Traverse();
// Iterator class can be used to
// sequentially access nodes of linked list
class Iterator
{
public:
Iterator() noexcept :
m_pCurrentNode (m_spRoot) { }
Iterator(const Node* pNode) noexcept :
m_pCurrentNode (pNode) { }
Iterator& operator=(Node* pNode)
{
this->m_pCurrentNode = pNode;
return *this;
}
// Prefix ++ overload
Iterator& operator++()
{
if (m_pCurrentNode)
m_pCurrentNode = m_pCurrentNode->pNext;
return *this;
}
// Postfix ++ overload
Iterator operator++(int)
{
Iterator iterator = *this;
++*this;
return iterator;
}
bool operator!=(const Iterator& iterator)
{
return m_pCurrentNode != iterator.m_pCurrentNode;
}
int operator*()
{
return m_pCurrentNode->data;
}
private:
const Node* m_pCurrentNode;
};
private:
class Node
{
T data;
Node* pNext;
// LinkedList class methods need
// to access Node information
friend class LinkedList;
};
// Create a new Node
Node* GetNode(T data)
{
Node* pNewNode = new Node;
pNewNode->data = data;
pNewNode->pNext = nullptr;
return pNewNode;
}
// Return by reference so that it can be used in
// left hand side of the assignment expression
Node*& GetRootNode()
{
return m_spRoot;
}
static Node* m_spRoot;
};
template
/*static*/ typename LinkedList::Node* LinkedList::m_spRoot = nullptr;
template
void LinkedList::push_back(T data)
{
Node* pTemp = GetNode(data);
if (!GetRootNode())
{
GetRootNode() = pTemp;
}
else
{
Node* pCrawler = GetRootNode();
while (pCrawler->pNext)
{
pCrawler = pCrawler->pNext;
}
pCrawler->pNext = pTemp;
}
}
template
void LinkedList::Traverse()
{
Node* pCrawler = GetRootNode();
while (pCrawler)
{
cout << pCrawler->data << " ";
pCrawler = pCrawler->pNext;
}
cout << endl;
}
//Driver program
int main()
{
LinkedList list;
// Add few items to the end of LinkedList
list.push_back(1);
list.push_back(2);
list.push_back(3);
cout << "Traversing LinkedList through method" << endl;
list.Traverse();
cout << "Traversing LinkedList through Iterator" << endl;
for ( LinkedList::Iterator iterator = list.begin();
iterator != list.end(); iterator++)
{
cout << *iterator << " ";
}
cout << endl;
return 0;
}
输出:
Traversing LinkedList through method
1 2 3
Traversing LinkedList through Iterator
1 2 3
锻炼:
当我们只有一个数据时,上述实现效果很好。扩展此代码以处理包装在类中的数据集。
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程” 。