简体   繁体   English

哈希表和BST实施

[英]Hashtable & BST Implementation

I'm working on an assignment that can accept commands from keyboard to insert people into a hashtable. 我正在做一个可以接受键盘命令将人插入哈希表的任务。 After someone is inserted into the hastable, they can be "friended" with another person in the table. 将某人插入hastable后,可以将他们与表中的其他人“成为朋友”。 The way I have to store who is friends with who is a binary search tree. 我必须存储谁与谁是二叉搜索树的朋友的方式。 What I have to do is for the hashtable the first part of the node would be the person's name, then then next is a pointer to the bst for that person's friends, and finally the end is a pointer to the next node for chaining if there is a collision. 对于哈希表,我要做的是节点的第一部分是该人的名字,然后接下来是该人朋友的bst指针,最后是如果要链接,则指向下一个要链接的节点的指针是一次碰撞。 Here is a visual example... 这是一个视觉示例... 在此处输入图片说明

I have been able to insert people into my table, but the problem that I can not figure out is how to access the BST and add in friends for that person. 我已经可以在表格中插入人,但是我不知道的问题是如何访问BST并为该人添加朋友。 Here is my code... 这是我的代码...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Structures
struct linkedList{
    char *name;
    struct linkedList *next;
    struct linkedList *tree;
};

typedef struct linkedList list;

struct hashTable{
    int size;
    list **table;
};

typedef struct hashTable hash;

struct bst{
    char *val;
    struct bst *l;
    struct bst *r;
};

int main(){
char input[50];
char *ch, cmd_str[50], name[30];

// Make hash table for names
hash *profiles;
profiles = createHashTable(1001);

while(1){
    // Get keyboard input
    fgets(input, 50, stdin);
    input[strlen(input)-1] = '\0';

    // parse the input
    ch = strtok(input, " ");
    strcpy(cmd_str,ch);



    if(strcmp("CREATE", cmd_str) == 0){
        ch = strtok(NULL, " \n");
        insertPerson(profiles, ch);
    }
    else if(strcmp("FRIEND", cmd_str) == 0){
        ch = strtok(NULL, " \n");
        strcpy(name, ch);
        ch = strtok(NULL, " \n");
        friendPerson(profiles, name, ch);
    }
    else if(strcmp("UNFRIEND", cmd_str) == 0){
        ch = strtok(NULL, " \n");

    }
    else if(strcmp("LIST", cmd_str) == 0){
        ch = strtok(NULL, " \n");
        printFriends(profiles, ch);
    }
    else if(strcmp("QUERY", cmd_str) == 0){

    }
    else if(strcmp("BIGGEST-FRIEND-CIRCLE", cmd_str) == 0){

    }
    else if(strcmp("INFLUENTIAL-FRIEND", cmd_str) == 0){

    }
    else if(strcmp("EXIT", cmd_str) == 0){
        printf("\nExiting...\n");
        return 0;
    }
    else{
        printf("\nBad Command.\n");
    }
}
}

// Creates Hash Table
hash *createHashTable(int size){
int i;
hash *new_table;

if((new_table = malloc(sizeof(hash))) == NULL)
    return NULL;

if((new_table->table = malloc(sizeof(list *) * size)) == NULL)
    return NULL;

for(i=0; i < size; i++)
    new_table->table[i] = NULL;

new_table->size = size;

return new_table;
}

// hashing function
int keyHash(char *name){
    int c;
    unsigned long key;

    while(c = *name++)
        key = ((key<<5) + key) + c;

    return key%1000;
 }

// insert a person into the hash table
void insertPerson(hash *profiles, char *name){
    struct linkedList *item = (struct linkedList*)malloc(sizeof(struct linkedList));
    int hash_val = keyHash(name);

    item->name = name;
    item->next = NULL;
    item->tree = new_tree;

    // Collision case
    if(profiles->table[hash_val] != NULL){
        while(profiles->table[hash_val]->next != NULL){
            profiles->table[hash_val] = profiles->table[hash_val]->next;
        }
        profiles->table[hash_val]->next = item;
    }
    // Empty cell
    else{
        profiles->table[hash_val] = item;
    }

}

// friend two people inside the hash table
void friendPerson(hash *profiles, char *name, char *_friend){
    int hash1 = keyHash(name);
    int hash2 = keyHash(_friend);

    // check if the names are already in system
    if(!profiles->table[hash1]){
        printf("%s is not yet in the system", name);
        return;
    }
    if(!profiles->table[hash2]){
        printf("%s is not yet in the system", _friend);
        return;
    }

    // add first friend
    if(strcmp(profiles->table[hash1]->name, name) == 0){
        insertBST(profiles->table[hash1]->tree, _friend);
    }
    else{
        while(profiles->table[hash1]->next != NULL){
            if(strcmp(profiles->table[hash1]->name, name) == 0)){
                break;
            }
            profiles->table[hash1] = profiles->table[hash1]->next;
        }
        insertBST(profiles->table[hash1]->tree, _friend);
    }

    // add second friend
    if(strcmp(profiles->table[hash2]->name, _friend) == 0){
        insertBST(profiles->table[hash2]->tree, name);
    }
    else{
        while(profiles->table[hash2]->next != NULL){
            if(strcmp(profiles->table[hash2]->name, name) == 0)){
                break;
            }
            profiles->table[hash2] = profiles->table[hash1]->next;
        }
        insertBST(profiles->table[hash2]->tree, name);
    }
}

// creates a new bst node
struct bst *newBSTNode(char *name){
    struct bst *temp = (struct bst* )malloc(sizeof(struct bst));
    temp->val = strdup(name);
    strcpy(temp->val, name);
    temp->l = temp->r = NULL;
    return temp;
}

// Inserts the a friend into a BST
struct bst *insertBST(struct bst *node, char *name){
    if(!node)
        return newBSTNode(name);
    else{
        if(strcmp(name, node->val) < 0){
            node->l = insertBST(node->l, name);
        }
        else if(strcmp(name, node->val) > 0){
            node->r = insertBST(node->r, name);
        }
    }

    return node;
}

// Inorder print of names
void inorder(struct bst *root){
    if(!root){
         inorder(root->l);
         printf("%s ", root->val);
         inorder(root->r);
    }
}

// Sends to function to print names
void printFriends(hash *profiles, char *name){
    int hash_val = keyHash(name);
    inorder(profiles->table[hash_val]->tree);
}

How would I be able to access the BST of said person? 我将如何访问该人的BST? The struct bst *tree = profiles->table[hash1]->tree; struct bst *tree = profiles->table[hash1]->tree; was my previous attempt, but it was more of a shot in the dark. 是我以前的尝试,但更多的是在黑暗中进行拍摄。 Thanks in advance! 提前致谢!

Update: Okay, so I have been able to add friends (I think) and now I'm trying to print them with void printFriends() . 更新:好的,所以我已经可以添加朋友了(我认为),现在我尝试使用void printFriends()打印他们。 However when I run the function nothing prints out. 但是,当我运行该功能时,不会打印任何内容。 Would anyone know where I'm messing it up? 有人知道我在哪里搞砸吗? I've updated the code above. 我已经更新了上面的代码。

Your linkedList stores the name and a tree pointer. 您的linkedList存储nametree指针。 But the type of tree is linkedList . 但是tree的类型是linkedList Change that to struct bst * . 将其更改为struct bst * You'll have to reorder the declarations, or insert a forward declaration. 您必须重新排列声明的顺序,或插入前向声明。

Implement a search. 实施搜索。 You check if the hash buckets are empty, but you don't search for the matching name. 您检查哈希存储桶是否为空,但不搜索匹配的名称。

Once you find a matching name in the bucket, the same node contains the aforementioned tree pointer. 在存储桶中找到匹配的名称后,同一节点将包含上述tree指针。 Insert the friend in the tree. 将朋友插入树中。 Depending on your logic, you may or may not want to insert a backreference in the other person's tree. 根据您的逻辑,您可能会或可能不想在其他人的树中插入反向引用。 (If Alice is friends with Bob, does that make Bob friends with Alice automatically? Or wait for confirmation?) (如果Alice是Bob的朋友,这会自动使Bob与Alice成为朋友吗?还是等待确认?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM