将节点添加到linked_list的前面允许或重复节点

时间:2019-03-14 16:37:24

标签: c++ linked-list hashtable

无法找出试图在链表的最前面添加节点时我的逻辑哪里出了问题。该程序允许双重输入和重复节点。现在要看逻辑一段时间,然后继续弄清楚我要出问题的地方。这个问题必须很简单,而且要仔细研究。似乎要继续将其添加到相同的linked_list中,而不是将每个用户添加到不同的列表中 导致的输入是 萨姆 丽莎 P标记 艾米 丽莎·艾米(F Liza Amy) 丽莎·马克 F艾米·萨姆

执行后,问题确实很清楚

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstring>

using namespace std;
void menu_function(void);
void command_execute( string command, string name1, string name2);
int hash_function(string str);
void insert_into_hashtable( int ascii_total, string name);
void add_friendship( int ascii_key, string name );
void print_friendships( int aascii_key);
void check_friendship( int ascii_key, string name);
void remove_friendship( int ascii_key, string name );

#define SIZE 150

struct friend_list
{
    string name;
    struct friend_list* next;
};

typedef struct friend_list list;

struct user{
    string name;
    int key;
    friend_list* FriendList;
};

struct user* hashArray[SIZE];

int main(int argc, const char * argv[]) {
    menu_function();
    return 0;
}
void menu_function(){
    char user_input[100];//this could limit the size of input
    string command;
    string name1 = "\0";
    string name2 = "\0";;
    char* token;
    int inputsize = 100;
    int i = 0;
    char delimit[]=" \t\r\n\v\f";
    while( 1 )
    {
        printf("\nP <Name> to create a person\n");
        printf("F <Name> <Name> record friendship\n");
        printf("U <Name> <Name> terminate friendship\n");
        printf("L <Name> print out friends of a specified person\n");
        printf("Q <Name> <Name>  check friendship status of two people\n");
        printf("X - terminate the progarm\n");
        // Determine user input and
        fgets(user_input, inputsize, stdin);
        //getline(&input, &inputsize, stdin);//takes in user input;
        //parsing e string for the data within
        token = strtok( user_input, delimit);
        i = 0;
        while( token != NULL ){
            if(i == 0)
            {
                command = token;
                //cout<< command<<endl;
            }
            if(i == 1)
            {
                name1 = token;
                // cout<< name1<<":"<<endl;
            }
            if( i == 2 )
            {
                name2 =  token;
                //  cout<< name2<<":"<<endl;
                name1 = name1 + "\n";
            }
            token = strtok( NULL, " " );
            i++;
        }
        command_execute( command, name1, name2);
        command = '\0';
        name1 = '\0';
        name2 = '\0';
    }
}
void command_execute( string command, string name1, string name2)
{
    //cout<<"command is: "<<command<<endl;
    switch( command[0])
    {
        case 'P': //Create record of the person
            insert_into_hashtable( hash_function(name1), name1);
            break;
        case 'F': //Record friendship
            add_friendship(hash_function(name1), name2);
            add_friendship(hash_function(name2), name1);
            break;
        case 'U': //Terminate Friendship
            remove_friendship( hash_function(name1), name2);
            remove_friendship( hash_function(name2), name1);
            break;
        case 'L': //Print out the persons Friends
            print_friendships( hash_function(name1));
            break;
        case 'Q': //Check on friendship
            check_friendship( hash_function(name1), name2);
            break;
        case 'X': //Exit the program **** COMPLETED
            exit(1);
            break;
        default:
            cout<<"Error occured based on your command please try again"<<endl;
            break;
    }
}
int hash_function(string string){
    //going to use the ASCI value of the name with different weights per array position to hash the names
    int ascii_key = 0;
    int ascii_total = 0;
    // cout<< string.length()<< endl;
    //cout<< string<< endl;
    for( int i = 0; i < string.length()-1; i++)
    {
        ascii_total = (int) string[i] * (i*3+1);
        //   cout<< string[i]<< endl;
    }
    ascii_key = ascii_total % SIZE;
    //deals with colisions through open hashing
    /*
     while(hashArray[ascii_key] != NULL || hashArray[ascii_key]-> key != ascii_key) { //strcmp(hashArray[ascii_key]->name.c_str(), string.c_str())
     //hashArray[ascii_key] != NULL ||
     ascii_key++;
     }
     */
    // ****** decide size of the hash table and then finished hashing function. Usually hash time is gonna be half full
    cout<< ascii_key<<endl;
    return ascii_key;
}
void insert_into_hashtable( int ascii_key, string name)
{
    //get the hash key
    user *item =  new user;
    item->name= name;
    item->key = ascii_key;
    item->FriendList = NULL;
    //cout<< ascii_key<<endl;
    //store the user in the table
    hashArray[ascii_key] = item;
    delete(item);
}
void add_friendship( int ascii_key, string name )
{
    //gonna have to check for valid input on users
    list* add  = new friend_list;
    list** temp = &hashArray[ascii_key]->FriendList;
    add->name =  name;
    add->next = NULL;
    if( temp == NULL )
     {
     //cout<<hashArray[ascii_key]->FriendList<<endl;
     *temp = add;
     }
     else
    {
        add->next = *temp;
        *temp = add;
    }
    print_friendships(ascii_key);
}
void print_friendships( int ascii_key)
{
    friend_list* temp  = hashArray[ascii_key]->FriendList;
    while( temp != NULL )
    {
        cout<<temp->name<<endl;
        if( temp->next == NULL)
        {
            return;
        }
        temp = temp->next;
    }
}

1 个答案:

答案 0 :(得分:1)

void insert_into_hashtable( int ascii_key, string name)
{
    //get the hash key
    user *item =  new user;
    item->name= name;
    item->key = ascii_key;
    item->FriendList = NULL;

    //store the user in the table
    hashArray[ascii_key] = item;
    delete(item);
}

为什么要删除该项目?

在数组中存储指针只是存储指针。它不会复制所指向的对象,或者以某种方式保护它免受显式删除。

已删除指向的对象,取消对指针的引用是未定义行为

您的错误可能发生是因为下一个分配的项重复使用了相同的内存(您明确表示可以使用delete来释放它),但是该实现可能合法地使您的计算机转向变成土豆,所以你可以轻松下车。

您可以确认-也许还会发现其他类似的问题,当您只需要编写固定的调用列表时-通过使用valgrind或地址清理器运行,我仍然不会浪费所有多余的I / O代码

在理想情况下,您实际上应该做的是停止完全使用低级原始指针和手动(取消)分配,而改为使用智能指针和惯用的C ++。