写一个函数接受 2 个参数——指针头或尾加上链表的遍历方向

Write a function takes in 2 parameters – the pointer head OR tail plus the direction to traverse for a linked list

这是我定义和初始化链表的方式

struct listrec
{
    struct listrec    *prev;
    float       value;
    struct listrec    *next;
};

listrec *head, *tail;

int main() {
int number;
cin >> number;
float content = 2.0;
    for (float i = 0; i < number; i++)
    {
        if (i == 0)
        {
            head = new listrec;
            head->prev = nullptr;
            head->value = 1.0;
            head->next = nullptr;
            tail = head;
        }
        else
        {
            auto *newNode = new listrec;
            newNode->value = content++;
            newNode->next = nullptr;
            newNode->prev = tail;
            tail->next = newNode;
            tail = tail->next;
        }
    }
return 0;
}

这是链表的样子

我需要“编写一个函数,它接受两个输入参数——指针头或尾加上一个遍历方向的参数——遍历链表和return数字列表中的元素数。 "

我不知道如何编写这样的函数...

我知道,如果我想从第一个节点开始计算元素的数量,那么我可以这样写一个函数:

float listSize(listrec* head)
{
    int count = 0; 
    listrec* current = head; // Initialize current  
    while (current != NULL)
    {
        count++;
        current = current->next;
    }
    return count;
}

或者,如果我想从最后一个元素开始计算元素,那么

float listSize2(listrec* tail)
{
    int count = 1;
    listrec* current = tail;
    while (tail->prev != NULL)
    {
        count++;
        tail = tail->prev;
    }
    return count;
}

但是我怎样才能将这两者结合起来呢?任何提示将不胜感激!

您不需要 "combine" 他们。您需要根据方向调用其中之一:

enum class Direction { Forward, Backwards };

int listSize(listrec* p, Direction dir)
{
     if (dir == Direction::Forward)
          return listSize(p);
     else
          return listSize2(p);
}

这不是评论网站,也就是说,如果没有对您的代码提出一些建议,我不能凭良心留下这个答案:

  • 在 C++ 中你应该使用 RAII。这样做的结果是您永远不应该使用对 new / delete 的显式调用,也不应该使用拥有原始指针。
  • count 是一个整数,所以在你的函数中 returning float 是没有意义的。浮点数据有其问题,不要将其用于整数。
  • 更好地命名您的函数。 listSizelistSize2 是糟糕的名字。您的函数没有 list,它们只是 return 大小。所以更好的名字是getSize。同样用数字来区分 then 是另一个糟糕的想法。您可以使用 getSizegetSizeReverse.
  • 无需将指针传递给您的函数。通过引用传递,甚至在您的情况下通过值传递是首选。
  • 您需要更好的 OOP 抽象。 listrec 是一个列表记录(又名列表节点)。最重要的是你需要一个 class 来抽象一个列表。这将包含一个指向列表头部的指针和一个指向列表尾部的指针。
  • 您应该创建一个用于插入列表的函数(和一个用于列表中的每个操作),而不是在 main 中手动执行。

这是函数,假设是一个双向链表:

enum class Direction {FORWARD, REVERSE};

struct Node
{
    Node * previous;
    Node * next;
};

unsigned int Count(Node * p_begin, Direction traverse_dir)
{
    unsigned int node_count = 0U;
    while (p_begin != nullptr)
    {
        ++node_count;
        if (traverse_dir == FORWARD)
        {
            p_begin = p_begin->next;
        }
        else
        {
            p_begin = p_begin->previous;
        }
    }
    return node_count;
}

根据要求,该函数采用 2 个参数,一个指向头节点或尾节点的指针,一个方向和 returns 遍历的节点数量。

函数从传递的指针开始,然后前进或后退(取决于方向参数),并递增节点计数器。当遇到空指针时循环停止,这通常表示列表的开始或结束。

由于只用到节点class,可以继承Node做各种列表类型:

struct Integer_Node : public Node
{
    int data;
};

数据域在链表遍历中不起作用,所以从基础节点对象中移除。