哈希表+二叉排序树

main.c 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "tree.h"
#include "hash.h"
#include "file.h"
#include "op.h"

int main(int argc, char **argv)
{
    int ret = -1;
    int op = -1;
    int key = -1;
    char YN = '\0';
    char filename[100] = "../Database.txt"; //数据库文件路径
    srand((unsigned int)time(NULL));        //随机数初始化
    HashTable *myhash = InitHashTable();    //哈希表初始化
    if (NULL == myhash)
    {
        return NULLERROR;
    }
    else
    {
        puts("提示:哈希表初始化完成!");
    }
    ret = InputTxt(myhash, filename);
    if (ret == 0)
    {
        puts("提示:信息载入完成!");
    }
    UserData mydata;                    //数据
    memset(&mydata, 0, sizeof(mydata)); //清空数据
    TreeNode *pnode = NULL;
    while (1)
    {
        if (NULL == myhash)
        {
            puts("提示:哈希表无法进行操作,已自动退出!");
            return NULLERROR;
        }
        menu(&op);
        switch (op)
        {
        case EXIT: //退出
        {

            if (OK == DestroyHashTable(&myhash))
            {
                puts("提示:哈希表清空内存!");
                puts("提示:退出系统!");
                return OK;
            }
            return ERROR;
            break;
        }
        case FIND: //搜索
        {
            printf("请输入编号:");
            scanf("%d", &key);
            FindHashTable(myhash, key);
            break;
        }
        case INSERT: //插入
        {
            printf("请输入插入信息!\n");
            memset(&mydata, 0, sizeof(mydata)); //清空数据
            printf("例子:220911887\n输入编号:");
            if (EOF == scanf("%d", &mydata.key))
            {
                puts("提示:输入格式错误!");
                memset(&mydata, 0, sizeof(mydata)); //清空数据
                break;
            }
            printf("例子:罗立红\n输入姓名:");
            if (EOF == scanf("%s", mydata.name))
            {
                puts("提示:输入格式错误!");
                memset(&mydata, 0, sizeof(mydata)); //清空数据
                break;
            }
            printf("例子:39\n输入年龄:");
            if (EOF == scanf("%d", &mydata.age))
            {
                puts("提示:输入格式错误!");
                memset(&mydata, 0, sizeof(mydata)); //清空数据
                break;
            }
            printf("例子:176\n输入身高:");
            if (EOF == scanf("%f", &mydata.height))
            {
                puts("提示:输入格式错误!");
                memset(&mydata, 0, sizeof(mydata)); //清空数据
                break;
            }
            printf("例子:18779338687\n输入手机号:");
            if (EOF == scanf("%ld", &mydata.tel))
            {
                puts("提示:输入格式错误!");
                memset(&mydata, 0, sizeof(mydata)); //清空数据
                break;
            }
            ret = InsertHashTable(myhash, &mydata);
            if (ret == 0)
            {
                puts("提示:插入信息完成!");
            }
            else
            {
                puts("提示:插入信息失败!");
            }
            memset(&mydata, 0, sizeof(mydata)); //清空数据
            break;
        }
        case DELETE: //删除
        {
            printf("请输入删除信息的编号:");
            scanf("%d", &mydata.key);
            ret = DeleteHashTable(myhash, &mydata);
            if (ret == 0)
            {
                puts("提示:删除信息完成!");
            }
            pnode = NULL;
            break;
        }
        case UPDATE: //更新
        {
            printf("请输入更新信息的编号:");
            scanf("%d", &mydata.key);
            UpdateHashTable(myhash, &mydata);
            puts("提示:更改完成!");
            break;
        }
        case SHOW: //查看
        {
            ShowHashTable(myhash);
            break;
        }
        case LOAD: //重新载入
        {
            printf("请输入文件路径:");
            scanf("%s", filename);
            ret = InputTxt(myhash, filename);
            if (OK == ret)
            {
                puts("提示:信息载入完成!");
            }
            else
            {
                puts("提示:信息载入失败!");
            }
            break;
        }
        case SAVE: //保存
        {
            ret = OutputTxt(myhash, filename);
            if (ret == 0)
            {
                puts("提示:信息已保存!");
            }
            else
            {
                puts("提示:信息保存失败!");
            }
            break;
        }
        case SAVEEXIT: //保存并退出
        {
            if (OK == OutputTxt(myhash, filename))
            {
                puts("提示:信息保存成功!");
                if (OK == DestroyHashTable(&myhash))
                {
                    puts("提示:哈希表清空内存!");
                    puts("提示:退出系统!");
                    return OK;
                }
                return ERROR;
            }
            else
            {
                puts("提示:信息保存失败!");
            }
            break;
        }
        default:
        {
            puts("提示:输入选项无效!");
            break;
        }
        }
    }
    return OK;
}

 tree.h

#ifndef _TREE_H_
#define _TREE_H_

//个数
#define N 100
//返回值枚举变量
enum ret
{
    FILEERROR = -4,
    MALLOCERROR = -3, //开辟空间错误
    NULLERROR,        //空指针错误
    ERROR,            //错误
    OK,               //正常
};
//数据类型
typedef struct _Data_
{
    float height;  //身高
    long tel;      //手机号
    int key;       //编号
    int age;       //年龄
    char name[20]; //姓名
} UserData;
//树结点
typedef struct _TreeNode_
{
    UserData data;             //数据域
    struct _TreeNode_ *left;   //左结点指针域
    struct _TreeNode_ *right;  //右结点指针域
    struct _TreeNode_ *parent; //父结点指针域
} TreeNode;
//树
typedef struct _Tree_
{
    TreeNode *root; //根节点指针
    int Treecount;  //树结点计数
} Tree;
//初始化二叉树
Tree *InitTree(void);
//创建二叉树结点
TreeNode *CreateTreeNode(const UserData *data);
//插入二叉树结点
int InsertTreeNode(Tree *T, TreeNode *pnode);
//查找二叉树
TreeNode *FindTreeNode(Tree *T, int key);
//删除树结点
TreeNode *DeleteTreeNode(Tree *T, TreeNode *pnode);
//查找左子树最大的结点(前驱结点)
TreeNode *LeftTreeMAX(TreeNode *pnode);
//查找右子树最小的结点(后继结点)
TreeNode *RightTreeMIN(TreeNode *pnode);
//查看树
int ShowTree(TreeNode *pnode);
//销毁树结点
int DestroyTreeNode(TreeNode **pnode);
//销毁树以下所有结点
int DestroyTree(Tree *T);
//制造随机数据
int CreateData(UserData *data);

#endif

tree.c 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tree.h"
//初始化二叉树
Tree *InitTree(void)
{
    Tree *T = NULL;
    T = (Tree *)malloc(sizeof(Tree)); //开辟树空间
    if (NULL == T)
    {
        return NULL;
    }
    memset(T, 0, sizeof(Tree));
    T->Treecount = 0; //初始化树
    T->root = NULL;
    return T;
}
//创建二叉树结点
TreeNode *CreateTreeNode(const UserData *data)
{
    if (NULL == data)
    {
        return NULL;
    }
    TreeNode *pnode = NULL;
    pnode = (TreeNode *)malloc(sizeof(TreeNode)); //开辟树结点空间
    if (NULL == pnode)
    {
        return NULL;
    }
    memset(pnode, 0, sizeof(TreeNode));
    pnode->data = *data; //初始化树结点
    pnode->left = NULL;
    pnode->right = NULL;
    pnode->parent = NULL;
    return pnode;
}
//插入二叉树结点
int InsertTreeNode(Tree *T, TreeNode *pnode)
{
    if (NULL == T || NULL == pnode)
    {
        return ERROR;
    }
    //若插入时是空树,则插入到根节点
    if (NULL == T->root)
    {
        T->root = pnode;
    }
    else //若非根结点
    {
        TreeNode *p1 = T->root;
        TreeNode *p2 = T->root;
        //找到插入结点的父结点地址
        while (NULL != p1)
        {
            p2 = p1;
            if (p1->data.key > pnode->data.key)
            {
                p1 = p1->left;
            }
            else if (p1->data.key < pnode->data.key)
            {
                p1 = p1->right;
            }
            else
            {
                puts("提示:已存在该结点!");
                return -1;
            }
        }
        //插入到左结点
        if (p2->data.key > pnode->data.key)
        {
            p2->left = pnode;
        }
        else //插入到右结点
        {
            p2->right = pnode;
        }
        pnode->parent = p2; //连接父结点
    }
    T->Treecount++; //树结点个树加1
    return 0;
}
//查找二叉树
TreeNode *FindTreeNode(Tree *T, int key)
{
    if (NULL == T)
    {
        return NULL;
    }
    TreeNode *p1 = T->root;
    //查找结点
    while (NULL != p1)
    {
        if (p1->data.key > key)
        {
            p1 = p1->left;
        }
        else if (p1->data.key < key)
        {
            p1 = p1->right;
        }
        else
        {
            printf("提示:已找到!\n");
            return p1;
        }
    }
    //没有查找到结点
    printf("提示:没找到%d!\n", key);
    return NULL;
}
//删除树结点
TreeNode *DeleteTreeNode(Tree *T, TreeNode *pnode)
{
    if (NULL == T || NULL == pnode)
    {
        return NULL;
    }
    TreeNode *p1 = pnode;
    //若结点是叶结点
    if (NULL == p1->left && NULL == p1->right)
    {
        if (T->root == p1) //若结点是根节点
        {
            T->root = NULL;
        }
        else
        {
            if (p1 == p1->parent->left)
            {
                p1->parent->left = NULL; //父结点的左分支指向NULL
            }
            else if (p1 == p1->parent->right)
            {
                p1->parent->right = NULL; //父结点的右分支指向NULL
            }
        }
        T->Treecount--; //树结点个树减1
    }
    //若结点有两个子结点
    else if (NULL != p1->left && NULL != p1->right)
    {
        //找到后继结点,数据跟后继结点交换,删除后继结点
        p1 = RightTreeMIN(p1->right);
        pnode->data = p1->data;
        DeleteTreeNode(T, p1);
    }
    //若结点有一个子结点
    else if (NULL != p1->left || NULL != p1->right)
    {
        if (T->root == p1) //若结点是根节点
        {
            if (NULL != p1->left)
            {
                T->root = p1->left;      //把子结点设置根节点
                p1->left->parent = NULL; //子结点的父指针清空
            }
            else if (NULL != p1->right)
            {
                T->root = p1->right;      //把子结点设置根节点
                p1->right->parent = NULL; //子结点的父指针清空
            }
        }
        else
        {
            if (p1 == p1->parent->left) //结点是父结点的左分支
            {
                if (NULL != p1->left) //结点有左分支
                {
                    p1->parent->left = p1->left;   //结点的父结点的左分支指向结点的左分支
                    p1->left->parent = p1->parent; //结点左分支的父指针指向结点的父结点
                }
                else if (NULL != p1->right) //结点有右分支
                {
                    p1->parent->left = p1->right;   //结点的父结点的左分支指向结点的右分支
                    p1->right->parent = p1->parent; //结点右分支的父指针指向结点的父结点
                }
            }
            else if (p1 == p1->parent->right)
            {
                if (NULL != p1->left)
                {
                    p1->parent->right = p1->left;
                    p1->left->parent = p1->parent;
                }
                else if (NULL != p1->right)
                {
                    p1->parent->right = p1->right;
                    p1->right->parent = p1->parent;
                }
            }
        }
        T->Treecount--; //树结点个树减1
    }
    return p1;
}
//查找左子树最大的结点(前驱结点)
TreeNode *LeftTreeMAX(TreeNode *pnode)
{
    if (NULL == pnode)
    {
        return NULL;
    }
    while (NULL != pnode->right) //左树右转
    {
        pnode = pnode->right;
    }
    return pnode;
}
//查找右子树最小的结点(后继结点)
TreeNode *RightTreeMIN(TreeNode *pnode)
{
    if (NULL == pnode)
    {
        return NULL;
    }
    while (NULL != pnode->left) //右树左转
    {
        pnode = pnode->left;
    }
    return pnode;
}
//查看树
int ShowTree(TreeNode *pnode)
{
    if (NULL == pnode)
    {
        return ERROR;
    }
    //中序输出
    ShowTree(pnode->left);
    printf("编号:%8d,姓名:%-10s,年龄:%-2d ,身高:%.1f,手机号:%ld;\n",
           pnode->data.key, pnode->data.name, pnode->data.age, pnode->data.height, pnode->data.tel);
    ShowTree(pnode->right);
    return OK;
}
//销毁树结点
int DestroyTreeNode(TreeNode **pnode)
{
    if (NULL == pnode)
    {
        return ERROR;
    }
    if (NULL == *pnode)
    {
        return OK;
    }
    DestroyTreeNode(&(*pnode)->left);                      //销毁左分支
    DestroyTreeNode(&(*pnode)->right);                     //销毁右分支
    if (NULL == (*pnode)->left && NULL == (*pnode)->right) //左右分支销毁完毕
    {
        memset((*pnode), 0, sizeof(TreeNode)); //清空内存
        free((*pnode));                        //释放内存
        *pnode = NULL;                         //指针指向NULL
    }
    else
    {
        puts("销毁树结点失败!");
        return ERROR;
    }
    return OK;
}
//销毁树所有结点,根节点指向NULL,数量清空
int DestroyTree(Tree *T)
{
    if (NULL == T)
    {
        return ERROR;
    }
    if (OK == DestroyTreeNode(&(T->root))) //若销毁完根节点
    {
        T->Treecount = 0; //树结点个数清零
        return OK;
    }
    return ERROR;
}
//制造随机数据
int CreateData(UserData *data)
{
    if (NULL == data)
    {
        return NULLERROR;
    }
    data->height = (float)(rand() % 200) / 10 + 160;    //身高160~180
    data->key = 22091 * 1000 + rand() % 1000;           //编号22091000~22091999
    data->age = 18 + rand() % 62;                       //年龄18~100
    data->tel = (long)1877933 * 10000 + rand() % 10000; //手机号18779330000~18779339999
    char temp[20] = {97 + rand() % 26, 97 + rand() % 26, 97 + rand() % 26, 97 + rand() % 26, 97 + rand() % 26, 97 + rand() % 26};
    strcpy(data->name, temp);
    return OK;
}

 op.h

#ifndef _OP_H_
#define _OP_H_

#include <tree.h>
#include <hash.h>
#include <file.h>

enum op
{
    EXIT = -1, //退出
    FIND = 1,  //搜索
    INSERT,    //插入
    DELETE,    //删除
    UPDATE,    //更新
    SHOW,      //查看
    LOAD,      //重新载入
    SAVE,      //保存
    SAVEEXIT   //保存并退出
};
//菜单函数
void menu(int *op);

#endif

 op.c

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

void menu(int *op)
{
    if (NULL == op)
    {
        return;
    }
    printf("——————————————————————————————————————————————————————————————————\n");
    printf("\t\t\t      菜单\n");
    printf("——————————————————————————————————————————————————————————————————\n");
    printf("\t\t\t 请输入操作选项\n");
    printf("\t\t\t 1——搜索编号\n");
    printf("\t\t\t 2——插入信息\n");
    printf("\t\t\t 3——删除信息\n");
    printf("\t\t\t 4——更改信息\n");
    printf("\t\t\t 5——查看所有信息\n");
    printf("\t\t\t 6——重新载入信息\n");
    printf("\t\t\t 7——保存当前信息\n");
    printf("\t\t\t 8——保存并退出\n");
    printf("\t\t\t-1——退出系统\n");
    printf("——————————————————————————————————————————————————————————————————\n");
    printf("请输入选项:");
    scanf("%d", op);
    return;
}

hash.h

#ifndef _HASH_H_
#define _HASH_H_

#include <tree.h>

//哈希表长
#define M 13
//哈希表
typedef struct _HashTable_
{
    Tree *tree;    //树指针
    int Hashcount; //哈希表结点计数
} HashTable;
//初始化哈希表
HashTable *InitHashTable(void);
//插入哈希表数据
int InsertHashTable(HashTable *myhashtable, UserData *mydata);
//删除哈希表数据
int DeleteHashTable(HashTable *myhashtable, UserData *mydata);
//更新哈希表数据
int UpdateHashTable(HashTable *myhashtable, UserData *mydata);
//查看哈希表数据
int ShowHashTable(HashTable *myhashtable);
//搜索哈希表数据
TreeNode *FindHashTable(HashTable *myhashtable, int key);
//哈希表信息数量
void HashTableCount(HashTable *myhashtable);
//哈希函数
int GetHash(int key);
//清空哈希表
int CleanHashTable(HashTable *myhashtable);
//销毁哈希表
int DestroyHashTable(HashTable **myhashtable);

#endif

hash.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hash.h"
//初始化哈希表
HashTable *InitHashTable(void)
{
    HashTable *phash = (HashTable *)malloc(sizeof(HashTable)); //开辟哈希表空间
    if (NULL == phash)
    {
        return NULL;
    }
    memset(phash, 0, sizeof(HashTable));
    phash->Hashcount = 0;                           //对哈希表初始化
    phash->tree = (Tree *)malloc(sizeof(Tree) * M); //开辟哈希表每个key空间。为了地址连续,没有用初始化树函数。
    if (NULL == phash->tree)
    {
        free(phash); //若开辟失败,则释放上次开辟的空间
        return NULL;
    }
    memset(phash->tree, 0, sizeof(HashTable) * M);
    int i = 0;
    for (i = 0; i < M; i++) //循环对每个key头数据初始化
    {
        phash->tree[i].Treecount = 0;
        phash->tree[i].root = NULL;
    }
    return phash; //返回哈希表
}
//插入哈希表
int InsertHashTable(HashTable *myhashtable, UserData *mydata)
{
    if (NULL == myhashtable || NULL == mydata)
    {
        return ERROR;
    }
    int KEY = GetHash(mydata->key); //获取KEY
    TreeNode *pnode = NULL;
    pnode = CreateTreeNode(mydata); //创建结点
    if (NULL != pnode)              //若成功创建结点
    {
        if (OK == InsertTreeNode(&myhashtable->tree[KEY], pnode)) //插入结点
        {
            return OK;
        }
    }
    return ERROR;
}
//删除哈希表数据
int DeleteHashTable(HashTable *myhashtable, UserData *mydata)
{
    if (NULL == myhashtable || NULL == mydata)
    {
        return ERROR;
    }
    int KEY = GetHash(mydata->key); //获取KEY
    TreeNode *pnode = NULL;
    pnode = FindTreeNode(&myhashtable->tree[KEY], mydata->key); //根据key查找结点
    if (NULL != pnode)                                          //若成功找到结点
    {
        pnode = DeleteTreeNode(&myhashtable->tree[KEY], pnode); //删除结点
        if (NULL != pnode)                                      //若成功删除结点
        {
            printf("编号:%8d,姓名:%-10s,年龄:%-2d ,身高:%.1f,手机号:%ld;\n",
                   pnode->data.key, pnode->data.name, pnode->data.age, pnode->data.height, pnode->data.tel);
            free(pnode); //释放结点
        }
        else
        {
            return ERROR;
        }
    }
    else
    {
        return ERROR;
    }
    return OK;
}
//更新哈希表数据
int UpdateHashTable(HashTable *myhashtable, UserData *mydata)
{
    if (NULL == myhashtable || NULL == mydata)
    {
        return ERROR;
    }
    int KEY = GetHash(mydata->key); //获取KEY
    TreeNode *pnode = NULL;
    pnode = FindTreeNode(&myhashtable->tree[KEY], mydata->key); //根据key查找结点
    if (NULL != pnode)                                          //若成功找到结点
    {
        *mydata = pnode->data;
        printf("原姓名:%s\n输入新姓名:", (*mydata).name);
        if (EOF == scanf("%s", (*mydata).name))
        {
            puts("提示:输入格式错误!");
            memset(mydata, 0, sizeof(mydata)); //清空数据
            return ERROR;
        }
        printf("原年龄:%d\n输入新年龄:", (*mydata).age);
        if (EOF == scanf("%d", &(*mydata).age))
        {
            puts("提示:输入格式错误!");
            memset(mydata, 0, sizeof(mydata)); //清空数据
            return ERROR;
        }
        printf("原身高:%.1f\n输入新身高:", (*mydata).height);
        if (EOF == scanf("%f", &(*mydata).height))
        {
            puts("提示:输入格式错误!");
            memset(mydata, 0, sizeof(mydata)); //清空数据
            return ERROR;
        }
        printf("原手机号:%ld\n输入新手机号:", (*mydata).tel);
        if (EOF == scanf("%ld", &(*mydata).tel))
        {
            puts("提示:输入格式错误!");
            memset(mydata, 0, sizeof(mydata)); //清空数据
            return ERROR;
        }
        pnode->data = *mydata;             //把新数据给该结点
        memset(mydata, 0, sizeof(mydata)); //清空数据
    }
    return OK;
}
//查看哈希表数据
int ShowHashTable(HashTable *myhashtable)
{
    if (NULL == myhashtable)
    {
        return ERROR;
    }
    HashTableCount(myhashtable); //计算哈希表结点数量
    printf("哈希表数据信息总量:%d\n", myhashtable->Hashcount);
    int i = 0;
    for (i = 0; i < M; i++)
    {
        printf("(KEY=%d)的%d条信息,详细信息如下:\n", i, myhashtable->tree[i].Treecount);
        ShowTree(myhashtable->tree[i].root);
    }
    printf("哈希表数据信息总量:%d\n", myhashtable->Hashcount);
    return OK;
}
//搜索哈希表数据
TreeNode *FindHashTable(HashTable *myhashtable, int key)
{
    if (NULL == myhashtable)
    {
        return NULL;
    }
    int KEY = GetHash(key);                                       //获取KEY
    TreeNode *pnode = FindTreeNode(&myhashtable->tree[KEY], key); //根据key查找结点
    if (NULL == pnode)
    {
        return NULL;
    }
    else
    {
        printf("编号:%8d,姓名:%-10s,年龄:%-2d ,身高:%.1f,手机号:%ld;\n",
               pnode->data.key, pnode->data.name, pnode->data.age, pnode->data.height, pnode->data.tel);
    }
    return pnode;
}
//哈希表信息数量
void HashTableCount(HashTable *myhashtable)
{
    if (NULL == myhashtable)
    {
        return;
    }
    myhashtable->Hashcount = 0;
    int i = 0;
    for (i = 0; i < M; i++)
    { //哈希表结点数量累加
        myhashtable->Hashcount = myhashtable->Hashcount + myhashtable->tree[i].Treecount;
    }
}
//哈希函数
int GetHash(int num)
{
    return num % M;
}
//清空哈希表
int CleanHashTable(HashTable *myhashtable)
{
    if (NULL == myhashtable)
    {
        return ERROR;
    }
    int i = 0;
    for (i = 0; i < M; i++)
    {
        if (OK != DestroyTree(&myhashtable->tree[i])) //清空每个key下面结点
        {
            return ERROR;
        }
    }
    return OK;
}
//销毁哈希表
int DestroyHashTable(HashTable **myhashtable)
{
    if (NULL == myhashtable || NULL == *myhashtable)
    {
        return ERROR;
    }
    if (OK == CleanHashTable(*myhashtable)) //清空哈希表下结点
    {
        free((*myhashtable)->tree); //释放结点头空间
        free(*myhashtable);         //释放哈希表空间
        *myhashtable = NULL;
        return OK;
    }
    return ERROR;
}

 file.h

#ifndef _FILE_H_
#define _FILE_H_

#include "hash.h"

//从文本文件到哈希表
int InputTxt(HashTable *myhashtable, char *filename);
//从哈希表到文本文件
int OutputTxt(HashTable *myhashtable, char *filename);
//中序输出至文件流
int ShowTreeTxt(FILE *fp, TreeNode *pnode);
#endif

file.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "file.h"
//从文本文件到哈希表
int InputTxt(HashTable *myhashtable, char *filename)
{
    if (NULL == myhashtable || NULL == filename)
    {
        return ERROR;
    }
    FILE *fp = fopen(filename, "r"); //打开文件
    if (NULL == fp)
    {
        printf("提示:无法打开文件!\n");
        return FILEERROR;
    }
    if (OK == CleanHashTable(myhashtable))
    {
        UserData data;    //数据
        while (!feof(fp)) //! feof(fp)判断标准IO文件流是否到末尾 文件IO是否到末尾用-1
        {
            memset(&data, 0, sizeof(data)); //清空数据
            //读取一组数据(5个)插入到哈希表一次
            if (5 == fscanf(fp, "%d%s%d%f%ld",
                            &data.key, data.name, &data.age, &data.height, &data.tel))
            {
                InsertHashTable(myhashtable, &data); //插入哈希表
            }
        }
        fclose(fp); //关闭文件
    }
    else
    {
        fclose(fp); //关闭文件
        printf("提示:清空旧数据失败!\n");
        return ERROR;
    }
    return OK;
}
//从哈希表到文本文件
int OutputTxt(HashTable *myhashtable, char *filename)
{
    if (NULL == myhashtable || NULL == filename)
    {
        return ERROR;
    }
    FILE *fp = fopen(filename, "w+"); //打开文件
    if (NULL == fp)
    {
        printf("提示:无法打开文件!\n");
        return FILEERROR;
    }
    int i = 0;
    for (i = 0; i < M; i++) //循环哈希表每个位置
    {
        ShowTreeTxt(fp, myhashtable->tree[i].root); //中序输出至文件流
    }
    fclose(fp); //关闭文件
    return OK;
}
//中序输出至文件流
int ShowTreeTxt(FILE *fp, TreeNode *pnode)
{
    if (NULL == fp || NULL == pnode)
    {
        return ERROR;
    }
    //中序输出至文件流
    ShowTreeTxt(fp, pnode->left);
    fprintf(fp, "%8d %-10s %-2d %.1f %ld\n",
            pnode->data.key, pnode->data.name, pnode->data.age, pnode->data.height, pnode->data.tel);
    ShowTreeTxt(fp, pnode->right);
    return OK;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值