数组和矢量都属于顺序存储结构(顺序表),由于链表和顺序表在存储结构上的差异,导致它们具有不同的特点,适用的应用场景也有所差异,感兴趣的小伙伴请猛击这里了解详情。
因为指向链表头的指针用于定位链表的头部,所以也可以认为它代表了链表头。同样的指针也可以用来定位整个链表,从头开始,后面跟着后续指针,所以也可以很自然地把它看作是代表了整个链表。nullptr 是 C++11 新增的一个关键字,专门替代 NULL、0 来初始化指针。和 NULL、0 相比,nullptr 可以使程序更健壮,具体原因请猛击这里了解详情。
struct ListNode
{
double value;
ListNode *next;
};
在以上代码中,ListNode 就是要存储在链表中的结点的类型,结构成员 value 是结点的数据部分,而另一个结构成员 next 则被声明为 ListNode 的指针,它是指向下一个结点的后继指针。注意,C++ 中的 struct 不仅可以定义结构体,还可以定义类(只是通常不这么做)。在 C++ 中,struct 和 class 基本是通用的,只有几个细节不同,感兴趣的小伙伴请猛击这里了解详情。
ListNode *head = nullptr;
现在可以创建一个链表,其中包含一个结点,存储值为 12.5,如下所示:head = new ListNode; //分配新结点 head->value = 12.5; //存储值 head->next = nullptr; //表示链表的结尾接下来再看一看如何创建一个新结点,在其中存储 13.5 的值,并将其作为链表中的第二个结点。可以使用第二个指针来指向新分配的结点(其中将存储 13.5 的值),示例如下:
ListNode *secondPtr = new ListNode; secondPtr->value = 13.5; secondPtr->next = nullptr; //第二个结点是链表的结尾 head->next = secondPtr; //第一个结点指向第二个请注意,以上语句通过将其后继指针 secondPtr->next 设置为 nullptr,可以使第二个结点成为链表的结尾,通过 head->next = secondPtr; 语句将链表头的后继指针改为指向第二个结点。
// This program illustrates the creation || of linked lists.
#include <iostream>
using namespace std;
struct ListNode
{
double value;
ListNode *next;
};
int main()
{
ListNode *head = nullptr;
// Create first node with 12.5
head = new ListNode; // Allocate new node
head->value = 12.5; // Store the value
head->next = nullptr; // Signify end of list
// Create second node with 13.5
ListNode *secondPtr = new ListNode;
secondPtr->value = 13.5;
secondPtr->next = nullptr; // Second node is end of list
head->next = secondPtr; // First node points to second
// Print the list
cout << "First item is " << head->value << endl;
cout << "Second item is " << head->next->value << endl;
return 0;
}
程序输出结果:
First item is 12.5
Second item is 13.5
struct ListNode
{
double value;
ListNode *next;
//构造函数
ListNode(double valuel, ListNode *nextl = nullptr)
{
value = value1;
next = next1;
}
};
通过该声明,即可使用以下两种不同的方式创建一个结点:
ListNode *secondPtr = new ListNode(13.5);
ListNode *head = new ListNode(12.5, secondPtr);
ListNode *head = new ListNode(13.5);
head = new ListNode(12.5, head);
head = new ListNode(12.5, head);
该语句将从右到左评估,首先在构造函数中使用 head 的旧值,然后从 new 运算符返回的地址将被分配给 head,成为它的新值。
ListNode *numberList = nullptr;
double number;
while (numberFile >> number)
{
//创建一个结点以保存该数字
numberList = new ListNode(number, numberList);
}
ListNode *ptr = numberList;
然后就可以通过使用表达式 *ptr 或者使用结构指针操作符 -> 来处理由 ptr 指向的结点。例如,如果需要打印在结点上的值,则可以编写以下代码:cout << ptr->value;
一旦在该结点的处理完成,即可将指针移动到下一个结点(如果有的话),其语句如下:ptr = ptr->next;
以上语句使用指向结点后继的指针来替换了指向该结点的指针,实现了结点之间的移动。因此,要打印整个链表,可以使用如下代码:
ListNode *ptr = numberList;
while (ptr != nullptr)
{
cout << ptr->value << " "; //处理结点(显示结点内容)
ptr = ptr->next; //移动到下一个结点
}
下面的程序演示了上面所介绍的各种技巧,即读取文件中的数字,将数字排列在链表中,然后通过遍历链表将数字显示在屏幕上。
// This program illustrates the building
// and traversal of a linked list.
#include <iostream>
#include <fstream>
using namespace std;
struct ListNode
{
double value;
ListNode *next;
// Constructor
ListNode(double value1, ListNode *next1 = nullptr)
{
value = value1; next = next1;
}
};
int main()
{
double number; // Used to read the file
ListNode *numberList = nullptr; // List of numbers
// Open the file
ifstream numberFile("numberFile•dat");
if (!numberFile)
{
cout << "Error in opening the file of numbers.";
exit (1);
}
//Read the file into a linked list
cout << "The contents of the file are: " << endl;
while (numberFile >> number)
{
cout << number << " ";
// Create a node to hold this number
numberList = new ListNode(number, numberList);
}
// Traverse the list while printing
cout << endl << "The contents of the list are: " << endl;
ListNode *ptr = numberList;
while (ptr != nullptr)
{
cout << ptr->value << " "; // Process node
ptr = ptr->next; // Move to next node
}
return 0;
}
程序输出结果:
The contents of the file are:
10 20 30 40
The contents of the list are:
40 30 20 10
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有