什么是构造函数?

构造函数 ,是一种特殊的方法。主要用来在 创建对象时初始化对象 , 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。

1、使用构造函数初始化结点

以下是ListNode 结构的另一个定义:

struct ListNode
{
    double value;
    ListNode *next;

    //构造函数
    ListNode(double valuel, ListNode *nextl = nullptr)
    {
        value = value1;
        next = next1;
    }
};

通过该声明,即可使用以下两种不同的方式创建一个结点:
① 通过仅指定其 value 部分,而后继指针则默认为 nullptr(一般用于当需要创建一个结点放在链表的末尾时 );
② 通过指定 value 部分和一个指向链表下一个结点的指针(一般用于当新创建的结点将被插入到链表中间某个有后继结点的地方时 )。

通过这个新的结点声明,即可使用更短的代码创建一个存储值 77.7 的结点,而它的后面则是一个存储值 777.7 的结点,示例如下:

ListNode *secondPtr = new ListNode(777.7);
ListNode *head = new ListNode(77.7, secondPtr);

实际上,还可以放弃第二个指针,将上面的代码改写为以下形式:

ListNode *head = new ListNode(777.7);
head = new ListNode(77.7, head); // 该语句将从右到左评估,首先在构造函数中使用 head 的旧值,然后从 new 运算符返回的地址将被分配给 head,成为它的新值。

2、创建链表

使用 ListNode 的构造函数版本,可以很轻松地创建一个链表,方法是读取文件中的值并将每个新读取的值添加到已经累积的值链表的开头。

例如,使用 numberList 作为链表头,使用 numberFile 作为输入文件对象,则以下代码将读取存储在某个文本文件中的数字,并将它们排列在链表中:

ListNode *numberList = nullptr;
double number;

while (numberFile >> number)
{
    //创建一个结点以保存该数字
    numberList = new ListNode(number, numberList);
}

3、遍历链表

从链表头开始,涉及整个链表,并在每个结点上执行一些处理操作的过程被称为遍历链表。

例如,如果需要打印某个链表中每个结点的内容,则必须遍历该链表。假设某个链表的链表头指针是 numberList,要遍历该链表,则需要使用另一个指针 ptr 指向链表的开头

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;

    // 构造函数
    ListNode(double value1, ListNode *next1 = nullptr)
    {
        value = value1; next = next1;
    }
};

int main()
{
    double number; 
    ListNode *numberList = nullptr; 

    // 打开 numberFile 文件
    ifstream numberFile("numberFile•dat");
    if (!numberFile)
    {
        cout << "Error in opening the file of numbers.";
        exit (1);
    }

    //将数据存入链表
    cout << "The contents of the file are: " << endl;
    while (numberFile >> number)
    {
        cout << number << " ";

        // 创建一个结点保存数据
        numberList = new ListNode(number, numberList);
    }

    //打印链表数据
    cout << endl << "The contents of the list are: " << endl;
    ListNode *ptr = numberList;
    while (ptr != nullptr)
    {
        cout << ptr->value << " "; 
        ptr = ptr->next; /
    }
    return 0;
}