如何在不使用 while 循环的情况下确定链表的大小
How to determine size of a Linked List without using a while loop?
我需要打印出链表中的节点数。我的老师说链表跟踪它的数据并"知道"其中有多少节点。因此,我应该不需要 while 循环来确定链表的大小。我很难找到一种除了 while 循环之外的方法来打印大小。
这是链表:
template <class T>
class LinkedList
{
private:
struct ListNode
{
T data ;
struct ListNode * next;
};
ListNode *head;
public:
LinkedList() { head = nullptr; }
~LinkedList();
// Linked list operations
void insertNode(T);
bool deleteNode(T);
void displayList() const;
};
/////////// Implementation portion of linked list with template //////////////
// displayList: print all list data
template <class T>
void LinkedList<T>::displayList() const
{
ListNode * ptr = head;
while (ptr != nullptr)
{
cout << ptr->data << endl;
ptr = ptr->next;
}
}
// insertNode: add a node in list order
template <class T>
void LinkedList<T>::insertNode(T newValue)
{
ListNode *newNode;
ListNode *pCur;
ListNode *pPre = NULL;
newNode = new ListNode;
newNode->data = newValue;
newNode->next = nullptr;
if (head == nullptr)
{
head = newNode;
}
else
{
pCur = head;
pPre = nullptr;
while (pCur != nullptr && pCur->data < newValue)
{
pPre = pCur;
pCur = pCur->next;
}
if (pPre == nullptr)
{
head = newNode;
newNode->next = pCur;
}
else
{
pPre->next = newNode;
newNode->next = pCur;
}
}
}
// deleteNode: delete a node if found
template <class T>
bool LinkedList<T>::deleteNode(T toBeDeleted)
{
ListNode *pCur;
ListNode *pPre;
if (!head)
return true;
pCur = head;
pPre = NULL;
while (pCur != NULL && pCur->data < toBeDeleted)
{
pPre = pCur;
pCur = pCur->next;
}
if (pCur != NULL && pCur->data == toBeDeleted)
{
if (pPre)
pPre->next = pCur->next;
else
head = pCur->next;
delete pCur;
return true;
}
return false;
}
// destructor, delete all nodes
template <class T>
LinkedList<T>::~LinkedList()
{
ListNode *ptr = head;
while (ptr != NULL)
{
head = head->next;
delete ptr;
ptr = head;
}
}
使用您定义的代码,列表的大小不会由列表直接存储。此外,链表的主要优点是每个节点都不知道列表的其余部分,并且存储大小会破坏这样做的目的。
但是,您可能误解了在不使用while
循环方面对您提出的要求。每个节点都知道它的长度是 1+(它的尾巴的长度),因此获取链表长度的更合适的实现是递归,而不是迭代。
下面是一个非常简单的 LinkedList 类的示例,它使用递归实现简单方法。如您所见,代码不使用迭代,只检查它自己的数据,然后为下一个节点调用相同的方法。尽管在大多数情况下,过程语言中的递归效率较低,但对于这样的结构,毫无疑问它是优雅的。
#include <iostream>
template<class T>
class LinkedList
{
private:
T data;
LinkedList* next;
public:
LinkedList()
: LinkedList(T()) {
}
LinkedList(T value)
: data(value), next(nullptr) {
}
~LinkedList() {
delete next;
}
void insertNode(T newValue) {
if (!next) {
next = new LinkedList(newValue);
return;
}
next->insertNode(newValue);
}
void displayList() const {
std::cout << data << std::endl;
if (next) {
next->displayList();
}
}
T& at(int N) {
if (N == 0) {
return this->data;
}
return next->at(N-1);
}
int size() {
if (!next) {
return 1;
}
return 1+next->size();
}
};
int main(int argc, char const *argv[])
{
LinkedList<int>* test = new LinkedList<int>(0);
for (int i = 1; i < 10; ++i) {
test->insertNode(i);
}
std::cout << "List of length: " << test->size() << std::endl;
test->displayList();
return 0;
}
您会注意到我没有包含deleteNode
,这是因为对于列表只有一个节点的情况,为上面的过度简化类编写它是不可能的。实现这一点的一种可能方法是拥有一个包装类,就像原始代码中的包装类一样,它是一个指向链表开头的指针。看这里。
相关文章:
- 传递链表而不在C++内存泄漏的情况下
- 我们可以在不使用head指针的情况下通过使用head的简单变量而不是head的指针来实现链表吗
- 在没有额外代码的情况下链接两个独立类的最通用方法是什么?
- 您可以在不使用类的情况下使用链表吗?
- 如何在没有参数的情况下实现返回双向链表大小的函数?int size() const.
- 如何在不使用 C++ 函数的情况下显示链表中的元素
- 如何在不更改C++中的原始链表的情况下反转链表
- 如何在没有CRT的情况下链接OBJ文件
- 链表在不使用循环的情况下反向
- 如何在没有外部脚本的情况下链接CMake和SQLite
- 无法在不使用RTTI构建LLVM的情况下链接LLVM编译器教程程序
- 在没有CRT,Memcpy和Memset固有函数的情况下链接误差
- 如何在不使用指针的情况下实现引用中的链表
- 如何在不使用指针的情况下实现链表
- 如何在忽略链接顺序的情况下链接源
- 链表程序挂在代码块调试器下,但在其他情况下正常执行
- HTML和C ++可以在没有任何外部应用程序的情况下链接
- 如何在不使用太多内存的情况下链接大量的c++对象文件
- 如何在不使用makefile的情况下链接对象文件和库
- 能够在没有pthreads的情况下链接,并且程序仍然运行