写一个函数接受 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
是没有意义的。浮点数据有其问题,不要将其用于整数。
- 更好地命名您的函数。
listSize
和 listSize2
是糟糕的名字。您的函数没有 list,它们只是 return 大小。所以更好的名字是getSize
。同样用数字来区分 then 是另一个糟糕的想法。您可以使用 getSize
和 getSizeReverse
.
- 无需将指针传递给您的函数。通过引用传递,甚至在您的情况下通过值传递是首选。
- 您需要更好的 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;
};
数据域在链表遍历中不起作用,所以从基础节点对象中移除。
这是我定义和初始化链表的方式
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
是一个整数,所以在你的函数中 returningfloat
是没有意义的。浮点数据有其问题,不要将其用于整数。- 更好地命名您的函数。
listSize
和listSize2
是糟糕的名字。您的函数没有 list,它们只是 return 大小。所以更好的名字是getSize
。同样用数字来区分 then 是另一个糟糕的想法。您可以使用getSize
和getSizeReverse
. - 无需将指针传递给您的函数。通过引用传递,甚至在您的情况下通过值传递是首选。
- 您需要更好的 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;
};
数据域在链表遍历中不起作用,所以从基础节点对象中移除。