3

我正在尝试从头开始制作一个由另一个类使用的简单链表。错误似乎是有时 Head 未设置为 NULL。我有时会说,它不会一直出现故障。它没有段错误的时间,它转到 else 语句。注意我只添加了 1 个字符串。也许你们可以发现我没有看到的东西,干杯!

链表.h:

#include <string>
#include "Link.h"

using namespace std;

class LinkedList {
  Link *head;

public:
  LinkedList();
  void addFront(string key);
  void printList();
  //void addBack(string *);     

};

链表.cpp:

#include <cstring>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "LinkedList.h"

using namespace std;

LinkedList::LinkedList() {
   head = NULL;
}

void LinkedList::addFront(string key) {
  //creates the new list segment                                                
  Link *l = new Link(key);

  cout << "Made new Link " << key << endl;
  // if the list is empty                                                 
  if (head == NULL){
    cout << "Going to set Head " << key << endl;
    head = l;
    cout << "Set Head to new link " << key << endl;
 }                                            
  else {             
     cout << "Else statement " << key << endl;                  
    l->setNext(head);

    head = l;
  }

}

void LinkedList::printList() {
 //Check if list is empty
  if(head == NULL)
   cout << "NULL" << endl;
  else {
   Link *l = head; 

   for(;l != NULL; l=l->getNext())
     cout << l->getValue() << endl;
  }


}

// void LinkedList::addBack(string *f) {
//   Link *l = new Link(f);

// }

链接.h

#include <cstdlib>
#include <cstring>
#include <string>

using namespace std;

class Link {
string key;
Link *next;

public:
    Link(string key);

    void setValue(char);
    void setNext(Link *next);
    string getValue();
    Link *getNext();
    void printList();

};

链接.cpp

#include <cstdlib>
#include <string>
#include <iostream>
#include "Link.h"

using namespace std;

Link::Link(string key) {
    this->key = key;
next = NULL;

}

void Link::setNext(Link *l) {
cout << "setting new link "<<endl;
next = l;

cout<< "New link was set" << endl;
}

string Link::getValue() {
return key;

}

Link *Link::getNext() {
return next;
}

哈希.h

#include <iostream>
#include <cstring>
#include <string>
#include "LinkedList.h"

using namespace std;

class Hash{
    //100 slot array for hash function
    LinkedList *hashFN[100];

    //preset prime number                                                               
  int prime = 101;
    int key;
  unsigned int location;

public:
    //Note: Both the key & values are the same 
    void insert(string key, string value);
    // void deleteItem(int key);
    // char* find(int key);


};

哈希.cpp:

#include <iostream>
#include <cstring>
#include <string>
#include "Hash.h"

using namespace std;

void Hash::insert(string k, string v){
    //Get Hash for argv[2] aka value                                                  
  size_t key = std::hash<string>()(k);
   unsigned int location;

//check 1                                                                         
  cout << "Hash: " << key << endl;

  //Find location
  location = key % prime;

  //check 2                                                                         
  cout << "Mod 101 Hash: " << location << endl;

    hashFN[location]->addFront(k);
    cout << "Success!" << endl;

}

// void Hash::deleteItem(int key){
//  return;

// }

// char* Hash::find(int key){
//  return;

// }

主文件

#include <iostream>
#include <functional>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include "Hash.h"                                                                   

using namespace std;

int main(int argc, char *argv[]) {

  Hash HashTable;                                                                   


  string Insert = string("insert");
  string Delete = string("delete");
  string Find   = string("find");
  string Argv(argv[2]);  //Makes the argv[2] into string type

  // check for Request & string parameters                                            
  if(argc != 3) {
    cout << "Run program with 2 parameters. [Lower Case]" << endl;
    cout << "[1] insert, find, or delete" << endl;
    cout << "[2] string" << endl;
    exit(1);
  }

  //Check for "insert"                                                                
  if(strcmp(argv[1], "insert") == 0) {


  HashTable.insert(Argv, Argv);                                                

  }

  return 0;
}
4

1 回答 1

3

您的直接问题:哈希表中的链表数组是指针数组。声明为:

LinkedList *hashFN[100];

您似乎从未分配任何这些对象。所以你只有一个包含 100 个指向垃圾的不确定指针的指针数组。要么分配它们,要么更好的是,直接实例化它们:

LinkedList hashFn[100];

这将要求您更改对它们的引用,例如

hashFN[location]->addFront(k);

变成这样:

hashFN[location].addFront(k);

接下来,您将使用非常量成员变量prime作为散列函数的模数。由于这是硬编码为101,因此您的表需要具有相同的大小。(事实上​​,我会完全丢失成员变量,而在你的 Hash.cpp 文件中只是一个静态常量)。但除此之外,问题仍然存在。你的桌子太小了一个槽。您的模数可以来自0..100,这意味着您需要一个[101]大小的表来处理所有这些插槽。请记住,C/C++ 中[0...(n-1)]的数组是针对大小数组寻址的n

所以至少像这样声明你的表:

LinkedList hashFN[101];

我要发布的最后一件事。你的链表像泰坦尼克号一样泄露。当列表被销毁时,您需要清理所有这些节点。在你的类中声明一个析构函数:

virtual ~LinkedList();

并在您的 .cpp 文件中像这样实现它:

LinkedList::LinkedList()
{
    while (head)
    {
        Link *victim = head;
        head = head->getNext();
        delete victim;
    }
}

好的。我撒了谎。还有一件事,在您能够轻松阅读理解三法则之前,您应该使您的课程不可复制。将以下内容放在 LinkedList 类声明的私有部分中:

class LinkedList
{
   ... other code...

private:
    LinkedList(const LinkedList&);
    LinkedList& operator =(const LinkedList&);
};

这将隐藏可能导致您出现重大问题的事情,直到您准备好正确实施它们。如果您发现自己出现“无法访问私有成员LinkedList(const LinkedList&)”的“错误”,那么您正在尝试制作副本,并且没有适当保护您的头指针,那就是不行。阅读三法则

剩下的交给你。

std::vector<>注意:使用标准库( 、等)有很多方法可以更轻松地完成这些工作std::unordered_map<>。事实上,它是所有这些的std::unordered_map<>替代品。但是,如果您只是对使用该语言再次熟悉该语言感兴趣,那么深入了解一下裸机也不错。只需专注于重新学习,然后学习使用标准库必须提供的所有漂亮代码。

于 2013-01-29T06:43:40.883 回答