我有一个链表数组,每个数组索引都包含链表。
除此之外,我还有另一个链表,按照我输入的确切顺序保存节点。
所以举个例子。 我的数组有500个索引。我在索引1上输入一个节点,在索引2上输入一个节点。 当我在索引1上打印链表时,它将只打印一个节点。但是,当我打印保存输入节点的确切顺序的链接列表时,它将按照我输入的顺序打印它们。
我已使用此代码
实现了此功能class CHash{
public:
CHash(){
for( int i = 0; i < 500 ;i++){
holder[i] = NULL;
}
first = NULL;
last = NULL;
};
void insert( string key , string value ){
size_t num = index(key);
Node *tmp;
if( holder[num] == NULL ){
tmp = new Node(key , value , NULL);
holder[num] = tmp;
}else{
tmp = new Node(key, value , holder[num]);
holder[num] = tmp;
}
if( first == NULL){
tmp -> nextNode = NULL;
tmp -> prevNode = NULL;
first = tmp;
last = tmp;
}else{
tmp -> prevNode = last;
last -> nextNode = tmp;
last = tmp;
}
}
void Print( size_t number ){
Node *tmp = holder[number];
while( tmp!= NULL){
cout << tmp -> value << endl;
tmp = tmp -> next;
}
}
void PrintAll(){
Node *tmp = first;
while( tmp != NULL){
cout << tmp -> value << endl;
tmp = tmp -> nextNode;
}
}
size_t index( string name ){
return name.length();
}
void de(string val){
size_t num = index(val);
if( holder[num] == NULL){
return;
}
Node *tmp = holder[num];
Node *help;
Node *help1;
while( tmp != NULL){
if( tmp -> key == val){
Node *temp = tmp;
if( tmp -> prevNode != NULL)
help = tmp -> prevNode;
else
help = NULL;
if( tmp -> nextNode != NULL)
help1 = tmp -> nextNode;
else
help1 = NULL;
if( tmp -> next != NULL){
tmp = tmp -> next;
tmp -> nextNode = help1;
tmp -> prevNode = help;
}
else
tmp = NULL;
delete temp;
return ;
}
tmp = tmp -> next;
}
}
它有效,让我感到困扰的是de
方法。它应该找到具有与参数相同的键的节点并将其删除。此删除应反映在两个链表中。我一直试图解决这个问题,但它总是会引发seg错误。
使用示例。
CHash one;
one.insert("two","cauko");
one.insert("tuk","hello");
one.insert("three","hrello");
one.Print(3) // should print "hello" , "cauko"
one.PrintAll() // should print "cauko" , "hello" , "hrello"
one.de("tuk");
one.Print(3); // should print only "cauko"
one.PrintAll(); // should print "cauko" , "hrello"
我在哪里弄错了?
答案 0 :(得分:3)
您应该为de
函数指定一个更明确的名称,添加注释,为单个任务创建更多函数,例如查找特定值的节点并提供完全可编译的代码。
de
下面的代码假设使用->next
的链接列表没有相应的prev
,因为没有关于此主题的信息。
void deleteVal(string val){
size_t num = index(val);
if( holder[num] == NULL){
return;
}
/* Find the key first */
Node* tmp = holder[num];
Node *prev = NULL;
while (tmp != NULL) {
if (tmp->key == val) {
break;
}
prev = tmp;
tmp = tmp->next;
}
if (tmp->key != val) {
//key not found
return;
}
/* remove the element from the global linked list */
if (tmp->prevNode) {
tmp->prevNode->nextNode = tmp->nextNode;
}
if (tmp->nextNode) {
tmp->nextNode->prevNode = tmp->prevNode;
}
if (first == tmp) {
first = tmp->nextNode;
}
if (last == tmp) {
last = tmp->prevNode;
}
/* Now remove the element from the linked list corresponding to index */
if (holder[num] == tmp) {
holder[num] = tmp->next;
} else {
prev->next = tmp->next;
}
//uncomment if the ->prev member exists in your class
// if (tmp->next) tmp->next->prev = tmp->prev;
/* Delete. */
delete tmp; //maybe tmp->next = tmp->nextNode = NULL before depending on your destructor
}
主要问题是您在代码中混合了两个链接列表:
if( tmp -> next != NULL){
tmp = tmp -> next;
tmp -> nextNode = help1;
tmp -> prevNode = help;
}
这两个链接列表彼此无关。
答案 1 :(得分:1)
我有一个链表数组,每个数组索引都包含链表。
除此之外,我还有另一个链接列表,它按照我输入的确切顺序保存节点。
您不应该在这些链接列表之间共享节点,除非您使用
之类的内容struct Node {
// ...
std::shared_ptr<Node> prev_node;
std::shared_ptr<Node> next_node;
};
答案 2 :(得分:1)
您正在尝试管理两个交织在一起的链接列表,而您正在将它们两者都粉碎。 在尝试这种复杂的事情之前,你必须掌握更简单的练习。
具体来说,问题在于:
if( tmp -> next != NULL){
tmp = tmp -> next;
tmp -> nextNode = help1;
tmp -> prevNode = help;
}
else
tmp = NULL;
您完全忽略了next
指向tmp
的节点。而不是通过help
和help1
(您的变量名称是可怕的)将两个节点相互连接,而是将它们连接到无关节点。