堆和哈希表的实现与应用(二)

来源:互联网 发布:考研 软件 编辑:程序博客网 时间:2024/06/11 00:41

堆的应用

对于堆的应用,我最熟悉的例子就是堆排序了(以升序排列为例)。算法思想:建立大根堆,每次取出根结点,与最后一个叶子节点就行交换,然后维持大根堆;依次递归实现堆排序。如下描述:

 

const int HEAP_SIZE = 1000;const int MAXN = 100000;template<class T>void Max_Heap(T h[], int p, int heap_size){    int tmp = h[p];    for(int q = p << 1; q <= heap_size; q <<= 1)    {        if(q < heap_size && h[q] < h[q+1]) ++q;        if(h[q] <= tmp) break;        h[p] = h[q];        p = q;    }    h[p] = tmp;}template<class T>void Build_Max_Heap(T h[], int heap_size){    for(int i = heap_size/2; i > 0; --i)        Max_Heap(h, i, heap_size);}template<class T>void HeapSort(T h[], int heap_size){    Build_Max_Heap(h, heap_size);    for(int i = heap_size; i > 1; --i)    {        swap(h[1], h[i]);        Max_Heap(h, 1, i-1);    }}

 

以上是我对堆的一些理解;如有错误,请大家谅解。

下面让我看看哈希表吧。对于哈希表我觉得自己没有什么发言权,请大家看看这个博客十一、从头到尾彻底解析Hash 表算法,写的特别的好。我就是从这篇博客学的哈希表。虽然没有完全领悟,但是也了解了一二。

哈希表和堆的应用

例题:给大家一本英文小说,在所有的单词中统计出前10个出现频率最多的单词。

 

/*功能说明:统计一本书中各单词的个数,打印出出现次数最多的前10个单词数据结构:哈希表、最小堆*/#include <iostream>#include <fstream>#include <cstring>#include <cassert>#include <cctype>using namespace std;const int HASH_SIZE = 87719;const int WORD_SIZE = 30;typedef struct node_hashTable *pstr_hashTable;typedef struct node_heap *pstr_heap;struct node_hashTable{    char *word;    int Wcnt;    pstr_hashTable next;};struct node_heap{    char word[WORD_SIZE];    int Wcnt;};pstr_hashTable hashTable[HASH_SIZE];int hash_function(const char *pstr){    int value = 0;    while(*pstr != '\0')    {        value = (value * 31 + *pstr++) % HASH_SIZE;    }    return value;}void appendWord_hashTable(const char *pstr){    int index = hash_function(pstr);    pstr_hashTable p = hashTable[index];    if(p != NULL)    {        while(p != NULL)        {            if(0 == strcmp(pstr, p->word))            {                p->Wcnt++;                return ;            }            p = p->next;        }        p = new node_hashTable;        p->Wcnt = 1;        p->word = new char[strlen(pstr) + 1];        strcpy(p->word, pstr);        p->next = NULL;    }    else    {        pstr_hashTable q = new node_hashTable;        q->Wcnt = 1;        q->word = new char[strlen(pstr) + 1];        strcpy(q->word, pstr);        hashTable[index] = q;        hashTable[index]->next = NULL;    }}void WriteToFile(){    FILE *fp = fopen("result.txt", "w");    assert(fp);    for(int i = 0; i < HASH_SIZE; ++i)    {        for(pstr_hashTable p = hashTable[i]; p != NULL; p = p->next)        {            fprintf(fp, "%s\t%d\n", p->word, p->Wcnt);        }    }    fclose(fp);}void handle_word(char *str, int n){    while (str[n] < '0' || (str[n] > '9' && str[n] < 'A') || (str[n] > 'Z' && str[n] < 'a') || str[n] > 'z')    {        str[n] = '\0';        n--;    }    while (str[0] < '0' || (str[0] > '9' && str[0] < 'A') || (str[0] > 'Z' && str[0] < 'a') || str[0] > 'z')    {        int i = 0;        while (i < n)        {            str[i] = str[i+1];            i++;        }        str[i] = '\0';        n--;    }    for(int i = 0; str[i] != '\0'; ++i)    {        if(str[i] >= 'A' && str[i] <= 'Z') str[i] = tolower(str[i]);    }}void ShitDown(pstr_heap heap, int i, int heap_size){    /*node_heap tmp;    tmp.Wcnt = heap[p].Wcnt;    memset(tmp.word, '\0', sizeof(char)*WORD_SIZE);    strcpy(tmp.word, heap[p].word);    for(int q = p << 1; p <= heap_size; q <<= 1)    {        if(q < heap_size && heap[q].Wcnt > heap[q + 1].Wcnt) q++;        if(heap[q].Wcnt >= tmp.Wcnt) break;        heap[p].Wcnt = heap[q].Wcnt;        char tmpBuff[WORD_SIZE];        memset(tmpBuff, '\0', sizeof(tmpBuff));        strcpy(tmpBuff, heap[q].word);        memset(heap[p].word, '\0', sizeof(char)*WORD_SIZE);        strcpy(heap[p].word, tmpBuff);        p = q;    }    heap[p].Wcnt = tmp.Wcnt;    memset(heap[p].word, '\0', sizeof(char)*WORD_SIZE);    strcpy(heap[p].word, tmp.word);    */    int min_index = -1;    int left = 2 * i;    int right = 2 * i + 1;    if (left <= heap_size && heap[left].Wcnt < heap[i].Wcnt)        min_index = left;    else        min_index = i;    if (right <= heap_size && heap[right].Wcnt < heap[min_index].Wcnt)        min_index = right;    if (min_index != i)    {        swap(heap[i].Wcnt, heap[min_index].Wcnt);        char buffer[WORD_SIZE];        strcpy(buffer, heap[i].word);        strcpy(heap[i].word, heap[min_index].word);        strcpy(heap[min_index].word, buffer);        ShitDown(heap, min_index, heap_size);    }}void BuildMinHeap(pstr_heap heap, int heap_size){    for(int i = heap_size/2; i > 0; --i)        ShitDown(heap, i, heap_size);}void DestroyHashTable(){    for(int i = 0; i < HASH_SIZE; ++i)        for(pstr_hashTable p = hashTable[i]; p != NULL; p = p->next)        {            delete [](p->word);            delete p;        }}int main(){    char str_word[WORD_SIZE];    memset(str_word, '\0', sizeof(str_word));    for(int i = 0; i < HASH_SIZE; ++i) hashTable[i] = NULL;    FILE *book = fopen("book.txt", "r");    assert(book);    while(fscanf(book, "%s", str_word) != EOF)    {        int n = strlen(str_word) - 1;        if(n >= 0)           handle_word(str_word, n);        appendWord_hashTable(str_word);    }    fclose(book);    WriteToFile();    int n = 10;    pstr_heap MinHeap = new node_heap[n+1];    int count = 0;    FILE *fp_word = fopen("result.txt","r");    assert(fp_word);    for(int i = 1; i <= n; ++i)    {        fscanf(fp_word, "%s %d", str_word, &count);        MinHeap[i].Wcnt = count;        strcpy(MinHeap[i].word, str_word);    }    BuildMinHeap(MinHeap, n);    while(fscanf(fp_word, "%s %d", str_word, &count) != EOF)    {        if(count > MinHeap[1].Wcnt)        {            MinHeap[1].Wcnt = count;            memset(MinHeap[1].word, '\0', sizeof(char)*WORD_SIZE);            strcpy(MinHeap[1].word, str_word);            ShitDown(MinHeap, 1, n);        }    }    fclose(fp_word);    for(int i = 1; i <= n; ++i)        cout << MinHeap[i].word << '\t' << MinHeap[i].Wcnt << endl;    DestroyHashTable();    return 0;}



 

原创粉丝点击