堆和哈希表的实现与应用(二)
来源:互联网 发布:考研 软件 编辑:程序博客网 时间: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;}
- 堆和哈希表的实现与应用(二)
- 堆的实现与应用
- 堆和哈希表的实现以及应用(一)
- 堆结构(二) - 左倾堆的原理与实现
- 堆排序算法二(堆排序算法的应用)
- 堆与栈的区别(二)
- 堆与栈的区别(二)
- 模拟实现堆+堆的应用
- 小白学数据结构——二、树与堆(基本概念及二叉树、二叉堆的python实现)
- 堆和栈的区别(二)
- 堆的介绍与应用
- 堆和堆的应用:堆排序和优先队列
- 最小堆与最大堆的实现
- 最大堆与最小堆的实现
- 栈与堆,String和StringBuffer(二)
- 第九周 项目二-对称矩形压缩存储的实现与应用(二)
- 排序算法的数组实现 -- 堆排序(二)
- 算法设计之堆的实现与堆排序实现(C++实现)
- 数组和链表,堆栈和堆
- Excel小技巧:给单元格打上勾
- 记住:不要使用!=,~=,^=,<>,=与NULL做比较
- X-Win32的安装以及使用详解
- 密码隐藏或显示
- 堆和哈希表的实现与应用(二)
- ubuntu12.04 无法自动挂载USB外设 问题的解决
- android 中XML和对象转换利器Xstream的使用
- mysql点滴记录
- exclude排除文件– rsync详解
- 关于shadow map
- Failed to transmit data to network: [10054] Connection reset by peer解决办法
- 深入理解cookie & session
- SQL Server日期