У вас было много проблем в вашем коде, давайте посмотрим, что они:
- Прежде всего,
Snode
не обязательно должен быть class
, скорее вы можете пойтис простым strcut
;так как нам нужно все public
. (не ошибка, а хорошая практика) - Вы можете просто инициализировать
count = 1
и next = nullptr
, так что нет необходимости инициализировать их конструктором throw.Единственный элемент, который нужно инициализировать через конструктор, это Snod's data
. - Поскольку
c++11
вы можете использовать ключевое слово nullptr
вместо NULL
, которое обозначает буквальный указатель . - Функция-член bool
set::isAvailable(char value)
не будет работать, как вы думаете.Здесь вы излишне создали new Snode
и проверяете, указывает ли он на nullptr
, что не позволяет вам даже войти в цикл.Кстати, то, что вы написали в цикле, тоже неправильно.Что вы подразумеваете под 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
}
}
Ваш деструктор не удалит все, что вы создали.Это будет UB, так как вы удаляете только что созданный
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;
}