我正在编写一个获得list
的简单应用,并将对象保存为<{em>单链表中的nodes
,我们可以add()
,{{ 1}},remove()
等每个节点取决于给定的数据集。每个节点都有copy()
这是我们的数据,char value
计算相关int count
的出现次数。
e.g。对于像
这样的列表a,a,b,b,c,a
将有三个节点(因为有三个不同的字符):
char
[a,3,*next] -> [b,2,*next] -> [c,1,*next] -> nullptr
检查数据是否已经在列表中。
问:插入数据时有两个选项:
尚未输入数据:因此我们必须使用给定数据bool isAvailable()
和newNode
创建count=1
。
已输入数据:因此我们必须*next=NULL
具有相同数据的节点。
我知道给定数据是否可用,但如何指向具有相同数据的节点?
以下是代码:
count++
答案 0 :(得分:2)
我知道给定数据是否可用,但如何指向具有相同数据的节点?
您需要从列表的开头开始,按照next
指针迭代列表,直到找到具有相同data
值的节点。完成后,您将指向具有相同数据的节点。
其他一些注意事项:
bool set::isAvailable(char value)
{
Snode *floatingNode = new Snode(char d, int c);
while(floatingNode != NULL)
{
return (value == floatingNode);
floatingNode->next = floatingNode;
}
}
为什么这个函数会分配new Snode
?没有理由这样做,只需将floatingNode
指针初始化为指向head
。
此功能始终仅在查看链接列表中的第一个节点后返回 - 这不是您想要的行为。相反,它应该仅在(value == floatingNode);否则它应该留在while循环中,以便它可以继续查看后续节点。只有在它退出while循环之后(因为floatingNode最终变为NULL)才会返回false。
如果您稍微修改isAvailable()
,以便返回true
或false
,而不是返回floatingPointer
或NULL
。 #39; d具有查找指向具有匹配数据的节点的指针的机制。
e.g:
// Should return either a pointer to the Snode with data==value,
// or NULL if no such Snode is present in the list
Snode * set::getNodeWithValueOrNullIfNotFound(char value) const
{
[...]
}
void set::insert(char value)
{
Snode * theNode = getNodeWithValueOrNullIfNotFound(value);
if (theNode != NULL)
{
theNode->count++;
}
else
{
[create a new Snode and insert it]
}
}
答案 1 :(得分:1)
您的代码中存在很多问题,让我们看看它们是什么:
Snode
不一定是class
,而是可以使用简单strcut
;因为我们需要一切public
。(不是错误,而是良好做法)count = 1
和next = nullptr
,这样就不需要初始化它们抛出构造函数。需要通过构造函数初始化的唯一元素是Snod的data
。c++11
开始,您可以使用关键字nullptr
代替NULL
,表示pointer literal。set::isAvailable(char value)
无法正常运作。在这里你不必要地创建了一个new Snode
,并且不知道它是否指向nullptr
,它不允许你甚至进入循环。 BTW你在循环中写的也错了。你return (value == floatingNode);
是什么意思? floatingNode
类型为Snode
;不是char
。听到正确的实施方式。由于我们不想覆盖头部,因此将创建一个Node*
指针并为其指定head
。然后遍历列表直到找到匹配项。如果找不到,我们将到达isAvailable()
的末尾并返回false
。
inline bool isAvailable(const char& value) { Node *findPos = head; while(findPos != nullptr) { if(findPos -> data == value) return true; else findPos = findPos->next_node; } return false; }
void set::insert(char value)
中,您的逻辑是正确的,但实施是错误的。以下是正确的实施。(希望评论能帮助您理解。void insert(const char& value) { if(head == nullptr) // first case { Node *newNode = new Node(value); newNode->next_node = head; head = newNode; } else if(isAvailable(value)) // if node available { Node *temp = head; while(temp->data != value) // find the node temp = temp->next_node; temp->count += 1; // and count it by 1 } else // all new nodes { Node *temp = head; while(temp->next_node != nullptr) // to find the null point (end of list) temp = temp->next_node; temp = temp->next_node = new Node(value); // create a node and assign there } }
Snode t
(即Snode *t = head;
)。正确的实现如下所示。(取消注释调试消息以理解。)~set() { Node* temp = head; while( temp != nullptr ) { Node* next = temp->next_node; //std::cout << "deleting \t" << temp->data << std::endl; delete temp; temp = next; } head = nullptr; }
最后但并非最不重要的是,命名(set
)你在这里所拥有的以及代码正在做什么都是不同的。这看起来更像是一个没有重复的简单链接列表。然而,这是好的,以便使用指针和列表。
为了使代码或迭代更有效,您可以执行以下操作。在isAvailable()
中,如果值匹配/如果找到node
,您也可以简单地增加其计数。然后在insert()
中,如果node
不是可用部分,您可以想到。
希望这有用。查看DEMO
#include <iostream>
// since you wanna have all of Node in public, declare as struct
struct Node
{
char data;
int count = 1;
Node* next_node = nullptr;
Node(const char& a) // create a constrcor which will initilize data
: data(a) {} // at the time of Node creation
};
class set
{
private:
Node *head; // need only head, if it's a simple list
public:
set() :head(nullptr) {} // constructor set it to nullptr
~set()
{
Node* temp = head;
while( temp != nullptr )
{
Node* next = temp->next_node;
//std::cout << "deleting \t" << temp->data << std::endl;
delete temp;
temp = next;
}
head = nullptr;
}
inline bool isAvailable(const char& value)
{
Node *findPos = head;
while(findPos != nullptr)
{
if(findPos -> data == value) return true;
else findPos = findPos->next_node;
}
return false;
}
void insert(const char& value)
{
if(head == nullptr) // first case
{
Node *newNode = new Node(value);
newNode->next_node = head;
head = newNode;
}
else if(isAvailable(value)) // if node available
{
Node *temp = head;
while(temp->data != value) // find the node
temp = temp->next_node;
temp->count += 1; // and count it by 1
}
else // all new nodes
{
Node *temp = head;
while(temp->next_node != nullptr) // to find the null point (end of list)
temp = temp->next_node;
temp = temp->next_node = new Node(value);
}
}
void print() const // just to print
{
Node *temp = head;
while(temp != nullptr)
{
std::cout << temp->data << " " << temp->count << "\n";
temp = temp->next_node;
}
}
};
int main()
{
::set mySet;
mySet.insert('a');
mySet.insert('a');
mySet.insert('b');
mySet.insert('b');
mySet.insert('c');
mySet.insert('a');
mySet.print();
return 0;
}