哈希链表:提高链表访问效率

本文探讨了如何利用哈希链表来提高数据访问的效率。链表作为一种动态数据结构,能够在未知数据大小的情况下灵活管理内存。通过在链表头部插入节点,实现了数据的动态生成。此外,文章还介绍了链表的遍历方法以及内存释放的策略,以完整的代码示例展示了链表操作的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表由一系列节点构成,节点可以在运行中动态生成。使用链表结构能够克服数组链表需要预先知道数据大小的缺点,充分利用计算机内存空间,实现灵活的内存动态管理。
当数据动态生成时,此时我们无法确知其数据大小,当然也无法进行判断了,而链表则可以解决此问题。针对上题文本数据,我们给出链表的解法。
首先,我们要熟悉下链表的创建过程:往链表头部加入新节点。

Node *head =nullptr;
while(...)
{
    Node* data=new Node;
    //读入数据
    //添加链表
    data->next = head;
    head = data;  //存放下个数据的地址

创建了链表之后,遍历链表节点的方法:

int cnt=0;
while (head)
{
    cout<<cnt<<" "<<head->id>>ends;
    cnt++;
    head = head->next;
}   

如图,链表结构为:
链表结构

链表的内存空间需要释放:

while(head)
{
    Node* tmp = head;
    head = head->next;
    delete tmp;
}

由于tmp和head指向统一内存单元,先让head指针指向下一个内存单元,再释放tmp指向的当前内存单元数据。

完整代码如下:

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

struct time
{
    int year,month,day;
    int hour,minute,second;
};

struct Node
{
    struct time tm;
    char id[20];
    char op[10];
    Node* next;

};


// 哈希算法:累计异或得到哈希值
int Hash(const char *str)
{
    int sum=0;
    for(int i=0;i<strlen(str);i++)
        sum ^= str[i];
    return sum;
}

// 加入哈希链表
void Insert(Node *Hash_tab[],Node elem)
{
    //计算每个编号的哈希值
    int idx=Hash(elem.id);
    //添加新的节点到链表头
    Node* data = new Node;
    *data=elem;
    data->next = Hash_tab[idx];
    Hash_tab[idx]=data;
}

// 释放一个链表内存
void Delete(Node* list)
{
    while(list)
    {
        Node* tmp = list;
        list=list->next;
        delete tmp;
    }
}

//  释放全部链表内存
void Release(Node* Hash_tab[])
{
    for(int i=0;i<256;i++)
    {
        if(Hash_tab[i]==nullptr)
            continue;
        Delete(Hash_tab[i]);
        Hash_tab[i]=nullptr;
    }
}

//  输出一条哈希链表
void Print(Node* list)
{
    while(list)
    {
        cout<<list->id<<endl;
        list=list->next;
    }
}

//  输出全部哈希链表
void Output(Node* Hash_tab[])
{
    for(int i=0;i<256;i++)
    {
        if(Hash_tab[i]==nullptr)
            continue;
        cout<<i<<" : "<<endl;
        Print(Hash_tab[i]);
        cout<<endl;
    }
}

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

    //链表指针初始化,不指向任何变量
    Node* list_tab[256]={nullptr};

    ifstream fin("log.txt");
    while(!fin.eof())
    {
        char tmp;
        Node data;
        //读入一行数据
        fin>>data.tm.year>>tmp>>data.tm.month>>tmp>>data.tm.day;
        fin>>data.tm.hour>>tmp>>data.tm.minute>>tmp>>data.tm.second;
        fin>>data.id;
        fin>>data.op;

        //添加至哈希链表
        Insert(list_tab,data);

    }
    fin.close();
    //输出哈希链表内容
    Output(list_tab);
    //释放哈希链表内存
    Release(list_tab);
     return 0;
}

当数据用二进制文件存取显示时,有如下定义: 
读文件 ifstream fin(filename, ios::binary);
写文件 ofstream fout(filename, ios::binary);
数据读取 fin.read((char*)&(data),sizeof(data));
数据写入 fin.write((char*)&(data),sizeof(data));

在之前的基础上,建立一个新的结构体

struct Log_item
{
    tm t;
    char id[20];
    char op[10];
};
struct Node
{
    Log_item log;
    Node* next;
};

主函数如下:

int main()
{
    ...//同前面操作
    Output(list_tab);
    //保存哈希表内容到二进制文件中
    SaveHashTab(list_tab,"list.tab");
    //释放哈希表内存
    Release(list_tab);
    //从二进制文件中重新载入哈希表
    LoadHashTab(list_tab,"list.tab");
    Output(list_tab);
    Release(list_tab);
    return 0;
}
//保存哈希表内容到二进制文件中
void SaveHashTab(Node* hash_tab[],const char* filename)
{
    ofstream  fout(filename,ios::binary);
    for(int i=0;i<256;i++)
    {
        Node* p =hash_tab[i];
        while(p)
        {
            fout.write((char*)&(p->log),sizeof(p->log));
            p=p->next;
        }
        fout.close();
}
// 从二进制文件中读取哈希表
void LoadHashTab(Node* hash_tab[],const char* filename)
{
    ifstream fin(filename,ios::binary);
    while(fin)
    {
        Node data;
        fin.read((char*)&(data->log),sizeof(data->log));
        if(fin.eof())
            break;
        Insert(hash_tab,data);
    }
    fin.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值