C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù))的示例代碼
要求
需要準(zhǔn)備數(shù)組集合(List) 數(shù)據(jù)結(jié)構(gòu)
需要準(zhǔn)備單向鏈表(Linked) 數(shù)據(jù)結(jié)構(gòu)
需要準(zhǔn)備紅黑樹(shù)(Rbtree)數(shù)據(jù)結(jié)構(gòu)
需要準(zhǔn)備紅黑樹(shù)和鏈表適配策略(文章內(nèi)部提供,可以自行參考)
建議先去閱讀我博客這篇文章C語(yǔ)言-手寫(xiě)Map(數(shù)組+鏈表)(全功能) 有助于理解
hashmap使用紅黑樹(shù)的原因是: 當(dāng)某個(gè)節(jié)點(diǎn)值過(guò)多的時(shí)候那么鏈表就會(huì)非常長(zhǎng),這樣搜索的時(shí)候查詢速度就是O(N) 線性查詢了,為了避免這個(gè)問(wèn)題我們使用了紅黑樹(shù),當(dāng)鏈表長(zhǎng)度大于8的時(shí)候我們轉(zhuǎn)換為紅黑樹(shù),當(dāng)紅黑樹(shù)的長(zhǎng)度小于6的時(shí)候轉(zhuǎn)換為鏈表,這樣既可以利用鏈表對(duì)內(nèi)存的使用率而且還可以使用紅黑樹(shù)的高效檢索,是一種很有效率的數(shù)據(jù)結(jié)構(gòu)。那么為啥不使用AVL樹(shù)呢? 因?yàn)锳VL樹(shù)是一種高度平衡的二叉樹(shù),所以查找的非常高,但是,有利就有弊,AVL樹(shù)為了維持這種高度的平衡,就要付出更多代價(jià)。每次插入、刪除都要做調(diào)整,復(fù)雜、耗時(shí)。所以,使用紅黑樹(shù)是最好的策略。
結(jié)構(gòu)
紅黑樹(shù)和鏈表轉(zhuǎn)換策略
#ifndef STUDY_LINKEDKVANDRBTREE_H #define STUDY_LINKEDKVANDRBTREE_H #include "charkvlinked.h" #include "rbtree.h" typedef int boolean;//定義一個(gè)布爾類(lèi)型 #define TRUE 1 #define FALSE 0 enum LINKEDKV_RBTREE_TYPE{LINKEDKV=0,RBTREE=1}; typedef struct linkedKvAndRbTree{ CharKvLinked *linked; // 鏈表 RBTree *rbTree; // 紅黑樹(shù) int len;// 長(zhǎng)度 enum LINKEDKV_RBTREE_TYPE type; // 類(lèi)型 } LinkedKvAndRbTree; #define isLinked(linkedKvAndRbTree) ((linkedKvAndRbTree != NULL) && (linkedKvAndRbTree->type == LINKEDKV)) ? TRUE : FALSE #define isRbtree(linkedKvAndRbTree) ((linkedKvAndRbTree != NULL) && (linkedKvAndRbTree->type == RBTREE)) ? TRUE : FALSE LinkedKvAndRbTree *createLinkedKvAndRbTree(); void linked_to_rbtree(LinkedKvAndRbTree *linkedKvAndRbTree); void rbtree_to_linked(LinkedKvAndRbTree *linkedKvAndRbTree); void insertOrUpdateLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key,char *value); void *searchLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key); void deleteLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key); CharKvLinked * getAllLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree); boolean isExistLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key); void destroyLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree); // 迭代器結(jié)構(gòu) typedef struct linkedKvAndRbTreeIterator { CharKvLinkedNode *next;// 迭代器當(dāng)前指向 int count;//迭代次數(shù) CharKvLinked *linked;//鏈表 int index; //位置 }LinkedKvAndRbTreeIterator; LinkedKvAndRbTreeIterator *createLinkedKvAndRbTreeIterator(LinkedKvAndRbTree *linkedKvAndRbTree); boolean hasNextLinkedKvAndRbTreeIterator(LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator); CharKvLinkedNode *nextLinkedKvAndRbTreeIterator(LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator); #endif //STUDY_LINKEDKVANDRBTREE_H
#include <stdio.h> #include "linkedKvAndRbTree.h" #include <stdlib.h> //創(chuàng)建 LinkedKvAndRbTree *createLinkedKvAndRbTree() { LinkedKvAndRbTree *linkedKvAndRbTree= malloc(sizeof(LinkedKvAndRbTree)); linkedKvAndRbTree->linked=NULL; linkedKvAndRbTree->rbTree=NULL; linkedKvAndRbTree->len=0; linkedKvAndRbTree->type=LINKEDKV;//默認(rèn)是鏈表,滿足條件則轉(zhuǎn)換為紅黑樹(shù)或者降級(jí)為鏈表 return linkedKvAndRbTree; } void linked_to_rbtree(LinkedKvAndRbTree *linkedKvAndRbTree){ //鏈表轉(zhuǎn)換為紅黑樹(shù)(不保證唯一性(可重復(fù)),自行判斷) if(linkedKvAndRbTree == NULL){ return; } if(isLinked(linkedKvAndRbTree)){ linkedKvAndRbTree->type = RBTREE; linkedKvAndRbTree->rbTree = createRBTree(); CharKvLinkedNode *node = linkedKvAndRbTree->linked->head; while(node != NULL){ insertRBTreeKeyRepetition(linkedKvAndRbTree->rbTree,createRbTreeNode(node->key,node->value)); node = node->next; } linkedKvAndRbTree->len = linkedKvAndRbTree->rbTree->size; //清除鏈表 destroyCharKvLinked(linkedKvAndRbTree->linked); linkedKvAndRbTree->linked=NULL; } } //紅黑樹(shù)轉(zhuǎn)換為鏈表(不保證唯一性(可重復(fù)),自行判斷) void rbtree_to_linked(LinkedKvAndRbTree *linkedKvAndRbTree){ if(linkedKvAndRbTree == NULL){ return; } if(isRbtree(linkedKvAndRbTree)){ linkedKvAndRbTree->type = LINKEDKV; linkedKvAndRbTree->linked = createCharKvLinked(); RBNode *node = linkedKvAndRbTree->rbTree->root; while(node != NULL){ insertCharKvLinkedHeadNode(linkedKvAndRbTree->linked,createCharKvLinkedNode(node->key,node->value)); node = node->right; } linkedKvAndRbTree->len = linkedKvAndRbTree->linked->len; //清除紅黑樹(shù) destroyRbTree(linkedKvAndRbTree->rbTree); linkedKvAndRbTree->rbTree=NULL; } } //插入時(shí)候key是唯一的,如果沖突那么就修改value void insertOrUpdateLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key,char *value){ if(linkedKvAndRbTree == NULL){ return; } if(isLinked(linkedKvAndRbTree)){ if(linkedKvAndRbTree->linked==NULL){ linkedKvAndRbTree->linked= createCharKvLinked(); } //長(zhǎng)度大于8的時(shí)候轉(zhuǎn)換為紅黑樹(shù) if(linkedKvAndRbTree->linked->len >=8){ linked_to_rbtree(linkedKvAndRbTree); insertOrUpdateRBTreeKey(linkedKvAndRbTree->rbTree,createRbTreeNode(key,value)); }else{ insertOrUpdateCharKvLinkedHeadNode(linkedKvAndRbTree->linked,createCharKvLinkedNode(key,value)); } }else if(isRbtree(linkedKvAndRbTree)){ if(linkedKvAndRbTree->rbTree==NULL){ linkedKvAndRbTree->rbTree=createRBTree(); } insertOrUpdateRBTreeKey(linkedKvAndRbTree->rbTree,createRbTreeNode(key,value)); }else{ return; } linkedKvAndRbTree->len++; } //查詢,返回節(jié)點(diǎn)的value void *searchLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key){ if(linkedKvAndRbTree == NULL){ return NULL; } if(isLinked(linkedKvAndRbTree)){ CharKvLinkedNode *pNode = searchCharKvLinked(linkedKvAndRbTree->linked, key); return pNode!=NULL?pNode->value:NULL; }else if(isRbtree(linkedKvAndRbTree)){ RBNode *pNode = searchRbTree(linkedKvAndRbTree->rbTree, key); return pNode!=NULL?pNode->value:NULL; } return NULL; } //判斷是否存在 boolean isExistLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key){ if(linkedKvAndRbTree == NULL){ return FALSE; } if(isLinked(linkedKvAndRbTree)){ return isExistCharKvLinked(linkedKvAndRbTree->linked,key); }else if(isRbtree(linkedKvAndRbTree)){ return isExistRbTree(linkedKvAndRbTree->rbTree,key); } return FALSE; } //刪除 void deleteLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key){ if(linkedKvAndRbTree == NULL){ return; } if(isLinked(linkedKvAndRbTree)){ delCharKvLinkedNode(linkedKvAndRbTree->linked,key); }else if(isRbtree(linkedKvAndRbTree)){ //長(zhǎng)度小于6的時(shí)候轉(zhuǎn)換為鏈表 if(linkedKvAndRbTree->rbTree->size <=6){ rbtree_to_linked(linkedKvAndRbTree); delCharKvLinkedNode(linkedKvAndRbTree->linked,key); } else{ removeRbTree(linkedKvAndRbTree->rbTree,key); } } else{ return; } linkedKvAndRbTree->len--; } //獲取所有的key和value CharKvLinked * getAllLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree){ if(linkedKvAndRbTree == NULL){ return NULL; } if(isLinked(linkedKvAndRbTree)){ return copyCharKvLinked(linkedKvAndRbTree->linked); }else if(isRbtree(linkedKvAndRbTree)){ return getAllKeyAndValueRbTree(linkedKvAndRbTree->rbTree); }else{ return NULL; } } //銷(xiāo)毀 void destroyLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree){ if(linkedKvAndRbTree == NULL){ return; } if(isLinked(linkedKvAndRbTree)){ destroyCharKvLinked(linkedKvAndRbTree->linked); }else if(isRbtree(linkedKvAndRbTree)){ destroyRbTree(linkedKvAndRbTree->rbTree); } free(linkedKvAndRbTree); } LinkedKvAndRbTreeIterator *createLinkedKvAndRbTreeIterator(LinkedKvAndRbTree *linkedKvAndRbTree) { LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator = malloc(sizeof(LinkedKvAndRbTreeIterator));; linkedKvAndRbTreeIterator->count = 0;//迭代次數(shù) linkedKvAndRbTreeIterator->linked = getAllLinkedKvAndRbTree(linkedKvAndRbTree); linkedKvAndRbTreeIterator->next = linkedKvAndRbTreeIterator->linked->head;//下次迭代節(jié)點(diǎn) return linkedKvAndRbTreeIterator; } boolean hasNextLinkedKvAndRbTreeIterator(LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator) { boolean pd=linkedKvAndRbTreeIterator->count < linkedKvAndRbTreeIterator->linked->len ? TRUE : FALSE; if(!pd){ free(linkedKvAndRbTreeIterator->linked); free(linkedKvAndRbTreeIterator); } return pd; } CharKvLinkedNode *nextLinkedKvAndRbTreeIterator(LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator) { if(!hasNextLinkedKvAndRbTreeIterator(linkedKvAndRbTreeIterator)){ return NULL; } CharKvLinkedNode *pNode = linkedKvAndRbTreeIterator->next; linkedKvAndRbTreeIterator->next =pNode->next;//切換到下一個(gè)節(jié)點(diǎn) linkedKvAndRbTreeIterator->count++; return pNode; }
hash
#ifndef STUDY_CHARHASH_H #define STUDY_CHARHASH_H #include "charlist.h" #include "../structure/linkedKvAndRbTree.h" typedef int boolean;//定義一個(gè)布爾類(lèi)型 #define TRUE 1 #define FALSE 0 // 哈希表結(jié)構(gòu)體 typedef struct hashMap { int size; // 集合元素個(gè)數(shù) int capacity; // 容量 int nodeLen; //節(jié)點(diǎn)長(zhǎng)度 LinkedKvAndRbTree **list; // 存儲(chǔ)區(qū)域 int dilatationCount; //擴(kuò)容次數(shù) int dilatationSum; //擴(kuò)容總次數(shù) } HashMap; HashMap *createHashMap(int capacity); void putHashMap(HashMap *hashMap, char *key, void *value); void printHashMap(HashMap *hashMap); void *getHashMap(HashMap *hashMap, char *key); boolean containsKey(HashMap *hashMap, char *key); boolean containsValue(HashMap *hashMap, void *value); void removeHashMap(HashMap *hashMap, char *key); void updateHashMap(HashMap *hashMap, char *key, void *value); CharList *getKeys(HashMap *hashMap); CharList *getValues(HashMap *hashMap); HashMap *copyHashMap(HashMap *hashMap); void mergeHashMap(HashMap *hashMap1,HashMap *hashMap2); HashMap *mergeHashMapNewMap(HashMap *hashMap1,HashMap *hashMap2); HashMap *differenceHashMap(HashMap *hashMap1,HashMap *hashMap2); HashMap *intersectionHashMap(HashMap *hashMap1,HashMap *hashMap2); HashMap *complementHashMap(HashMap *hashMap1,HashMap *hashMap2); HashMap *unionHashMap(HashMap *hashMap1,HashMap *hashMap2); void hashMapClear(HashMap *hashMap); // 迭代器結(jié)構(gòu) typedef struct hashMapIterator { LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator;// 迭代器 CharKvLinkedNode *next;// 下次的值 int count;//迭代次數(shù) HashMap *hashMap; int index; //位置 }HashMapIterator; // 創(chuàng)建哈希結(jié)構(gòu)迭代器 HashMapIterator *createHashMapIterator(HashMap *hashMap); // 迭代器是否有下一個(gè) boolean hasNextHashMapIterator(HashMapIterator *iterator); // 迭代到下一次 CharKvLinkedNode *nextHashMapIterator(HashMapIterator *iterator); #endif //STUDY_CHARHASH_H
#include "charHash.h" #include <stdio.h> #include <string.h> #include <stdlib.h> //最好的char類(lèi)型的hash算法,沖突較少,效率較高 static unsigned int BKDRHash(char *str) { unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } //hash值長(zhǎng)度取模最后獲取實(shí)際位置的下標(biāo) static unsigned int defaultHashCode(HashMap hashMap, char *key) { return BKDRHash(key) % hashMap.capacity; } // 創(chuàng)建Map集合 HashMap *createHashMap(int capacity) { //創(chuàng)建哈希表 HashMap *hashMap = (HashMap *) malloc(sizeof(HashMap)); //創(chuàng)建存儲(chǔ)區(qū)域 if (capacity < 10) { capacity = 10; } hashMap->size = 0; hashMap->dilatationCount = 0; hashMap->dilatationSum = 0; hashMap->nodeLen = 0; hashMap->capacity = capacity; hashMap->list = (LinkedKvAndRbTree **) calloc(capacity, sizeof(LinkedKvAndRbTree)); return hashMap; } //擴(kuò)容基數(shù) static int expansionBase(HashMap *hashMap) { int len = hashMap->capacity; int dilatationCount = hashMap->dilatationCount; hashMap->dilatationSum++; //基礎(chǔ)擴(kuò)容 len += (len >= 100000000 ? len * 0.2 : len >= 50000000 ? len * 0.3 : len >= 10000000 ? len * 0.4 : len >= 5000000 ? len * 0.5 : len >= 1000000 ? len * 0.6 : len >= 500000 ? len * 0.7 : len >= 100000 ? len * 0.8 : len >= 50000 ? len * 0.9 : len * 1.0); hashMap->dilatationCount++; //頻率擴(kuò)容 if (dilatationCount >= 3) { len += (len >= 100000000 ? len * 1 : len >= 50000000 ? len * 2 : len >= 10000000 ? len * 3 : len >= 5000000 ? len * 4 : len >= 1000000 ? len * 5 : len >= 500000 ? len * 6 : len >= 100000 ? len * 7 : len >= 50000 ? len * 8 : len >= 10000 ? len * 9 : len >= 1000 ? len * 10 : len * 20); hashMap->dilatationCount = 0; } return len; } //擴(kuò)容Map集合 static void dilatationHash(HashMap *hashMap) { //原來(lái)的容量 int capacity = hashMap->capacity; //擴(kuò)容后的容量 hashMap->capacity = expansionBase(hashMap); //節(jié)點(diǎn)長(zhǎng)度清空 hashMap->nodeLen = 0; //創(chuàng)建新的存儲(chǔ)區(qū)域 LinkedKvAndRbTree **newList = (LinkedKvAndRbTree **) calloc(hashMap->capacity, sizeof(LinkedKvAndRbTree)); for (int i = 0; i < capacity; ++i) { //獲取舊的存儲(chǔ)區(qū)域的每個(gè)節(jié)點(diǎn) LinkedKvAndRbTree *node = hashMap->list[i]; //如果節(jié)點(diǎn)不為空,將舊的節(jié)點(diǎn)所有數(shù)據(jù)放入新的存儲(chǔ)區(qū)域 if (node != NULL) { //拿到舊節(jié)點(diǎn)的所有key和value CharKvLinked *pCharKvLinked = getAllLinkedKvAndRbTree(node); //遍歷每個(gè)key和value,將每個(gè)key和value放入新的存儲(chǔ)區(qū)域 CharKvLinkedIterator *pIterator = createCharKvLinkedIterator(pCharKvLinked); while (hasNextCharKvLinkedIterator(pIterator)) { CharKvLinkedNode *pNode = nextCharKvLinkedIterator(pIterator); //獲取新的存儲(chǔ)區(qū)域的下標(biāo) unsigned int index = defaultHashCode(*hashMap, pNode->key); //將舊的節(jié)點(diǎn)放入新的存儲(chǔ)區(qū)域 LinkedKvAndRbTree *linkedKvAndRbTree = newList[index]; if (linkedKvAndRbTree == NULL) { //如果新存儲(chǔ)區(qū)域的節(jié)點(diǎn)為空,創(chuàng)建新的節(jié)點(diǎn) LinkedKvAndRbTree *newLinkedKvAndRbTree = createLinkedKvAndRbTree(); insertOrUpdateLinkedKvAndRbTree(newLinkedKvAndRbTree, pNode->key, pNode->value); newList[index] = newLinkedKvAndRbTree; hashMap->nodeLen++; //節(jié)點(diǎn)長(zhǎng)度加1 } else { //如果新存儲(chǔ)區(qū)域的節(jié)點(diǎn)不為空,將舊的節(jié)點(diǎn)放入新的存儲(chǔ)區(qū)域 insertOrUpdateLinkedKvAndRbTree(linkedKvAndRbTree, pNode->key, pNode->value); } } } } //釋放舊的存儲(chǔ)區(qū)域 free(hashMap->list); //將新的存儲(chǔ)區(qū)域賦值給舊的存儲(chǔ)區(qū)域 hashMap->list = newList; } //給Map集合添加元素 void putHashMap(HashMap *hashMap, char *key, void *value) { //判斷是否需要擴(kuò)容 if (hashMap->nodeLen == hashMap->capacity) { dilatationHash(hashMap); } //獲取hash值 unsigned int hashCode = defaultHashCode(*hashMap, key); //獲取節(jié)點(diǎn) LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode]; //如果節(jié)點(diǎn)是空的那么直接添加 if (linkedKvAndRbTree == NULL) { //如果新存儲(chǔ)區(qū)域的節(jié)點(diǎn)為空,創(chuàng)建新的節(jié)點(diǎn) LinkedKvAndRbTree *newLinkedKvAndRbTree = createLinkedKvAndRbTree(); insertOrUpdateLinkedKvAndRbTree(newLinkedKvAndRbTree, key, value); hashMap->list[hashCode] = newLinkedKvAndRbTree; hashMap->size++; hashMap->nodeLen++; return; } //如果節(jié)點(diǎn)不為空,那么就插入或者修改 insertOrUpdateLinkedKvAndRbTree(linkedKvAndRbTree, key, value); hashMap->size++; } //打印Map集合 void printHashMap(HashMap *hashMap) { for (int i = 0; i < hashMap->capacity; i++) { LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[i]; if (linkedKvAndRbTree != NULL) { CharKvLinked *pLinked = getAllLinkedKvAndRbTree(linkedKvAndRbTree); printCharKvLinked(pLinked); } } } //獲取Map集合中的元素 void *getHashMap(HashMap *hashMap, char *key) { //獲取hash值 unsigned int hashCode = defaultHashCode(*hashMap, key); //獲取節(jié)點(diǎn) LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode]; //如果節(jié)點(diǎn)是空的那么直接返回 if (linkedKvAndRbTree == NULL) { return NULL; } //獲取節(jié)點(diǎn)中的值 return searchLinkedKvAndRbTree(linkedKvAndRbTree, key); } //判斷鍵是否存在 boolean containsKey(HashMap *hashMap, char *key) { //獲取hash值 unsigned int hashCode = defaultHashCode(*hashMap, key); //獲取節(jié)點(diǎn) LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode]; //如果節(jié)點(diǎn)是空的那么直接返回FALSE if (linkedKvAndRbTree == NULL) { return FALSE; } return isExistLinkedKvAndRbTree(linkedKvAndRbTree, key); } //刪除Map集合中的元素 void removeHashMap(HashMap *hashMap, char *key) { //獲取hash值 unsigned int hashCode = defaultHashCode(*hashMap, key); //獲取節(jié)點(diǎn) LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode]; //如果節(jié)點(diǎn)是空的那么直接返回 if (linkedKvAndRbTree == NULL) { return; } //判斷是否存在該鍵,并且一樣的話,刪除該節(jié)點(diǎn) if (isExistLinkedKvAndRbTree(linkedKvAndRbTree, key)) { deleteLinkedKvAndRbTree(linkedKvAndRbTree, key); hashMap->size--; return; } } //修改Map集合中的元素 void updateHashMap(HashMap *hashMap, char *key, void *value) { //獲取hash值 unsigned int hashCode = defaultHashCode(*hashMap, key); //獲取節(jié)點(diǎn) LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode]; //如果節(jié)點(diǎn)是空的那么直接返回 if (linkedKvAndRbTree == NULL) { return; } //判斷是否存在該鍵,然后進(jìn)行修改 if (isExistLinkedKvAndRbTree(linkedKvAndRbTree, key)) { insertOrUpdateLinkedKvAndRbTree(linkedKvAndRbTree, key, value); } } HashMapIterator *createHashMapIterator(HashMap *hashMap) { HashMapIterator *pVoid = malloc(sizeof(HashMapIterator)); pVoid->hashMap = hashMap; pVoid->index = 0; pVoid->count = 0; LinkedKvAndRbTree *pTree = hashMap->list[pVoid->index]; //找到不是空的節(jié)點(diǎn) while (pTree == NULL) { pTree = hashMap->list[++pVoid->index]; } //創(chuàng)建迭代器 pVoid->linkedKvAndRbTreeIterator = createLinkedKvAndRbTreeIterator(pTree); //獲取迭代器中的第一個(gè)節(jié)點(diǎn) pVoid->next = nextLinkedKvAndRbTreeIterator(pVoid->linkedKvAndRbTreeIterator);; ++pVoid->index; return pVoid; } boolean hasNextHashMapIterator(HashMapIterator *iterator) { boolean pd = iterator->count < iterator->hashMap->size ? TRUE : FALSE; if (!pd) { free(iterator); } return pd; } CharKvLinkedNode *nextHashMapIterator(HashMapIterator *iterator) { if (!hasNextHashMapIterator(iterator)) { return NULL; } CharKvLinkedNode *entry = iterator->next; //獲取下一個(gè)節(jié)點(diǎn) CharKvLinkedNode *nextNode = nextLinkedKvAndRbTreeIterator(iterator->linkedKvAndRbTreeIterator); if (nextNode != NULL) { iterator->next = nextNode; } else { //如果是最后一個(gè)節(jié)點(diǎn)了,那么就不在找下個(gè)節(jié)點(diǎn)了 if (iterator->count + 1 < iterator->hashMap->size) { //獲取下一個(gè)節(jié)點(diǎn) LinkedKvAndRbTree *pTree = iterator->hashMap->list[iterator->index]; while (pTree == NULL) { pTree = iterator->hashMap->list[++iterator->index]; } iterator->linkedKvAndRbTreeIterator = createLinkedKvAndRbTreeIterator(pTree); iterator->next = nextLinkedKvAndRbTreeIterator(iterator->linkedKvAndRbTreeIterator);; ++iterator->index; } } iterator->count++; return entry; } //獲取所有的key ,返回一個(gè)自定義的List集合 CharList *getKeys(HashMap *hashMap) { CharList *pCharlist = createCharList(hashMap->size); HashMapIterator *pIterator = createHashMapIterator(hashMap); while (hasNextHashMapIterator(pIterator)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator); addCharList(&pCharlist, entry->key); } return pCharlist; } //獲取所有的value,返回一個(gè)自定義的List集合 CharList *getValues(HashMap *hashMap) { CharList *pCharlist = createCharList(hashMap->size); HashMapIterator *pIterator = createHashMapIterator(hashMap); while (hasNextHashMapIterator(pIterator)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator); addCharList(&pCharlist, entry->value); } return pCharlist; } //復(fù)制一個(gè)HashMap HashMap *copyHashMap(HashMap *hashMap) { HashMap *pHashMap = createHashMap(hashMap->capacity); HashMapIterator *pIterator = createHashMapIterator(hashMap); while (hasNextHashMapIterator(pIterator)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator); putHashMap(pHashMap, entry->key, entry->value); } return pHashMap; } //將一個(gè)map集合,合并到另一個(gè)map集合里 hashMap2合并到hashMap1 void mergeHashMap(HashMap *hashMap1, HashMap *hashMap2) { HashMapIterator *pIterator = createHashMapIterator(hashMap2); while (hasNextHashMapIterator(pIterator)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator); putHashMap(hashMap1, entry->key, entry->value); } } //合并兩個(gè)Map集合,返回一個(gè)新的Map集合 HashMap *mergeHashMapNewMap(HashMap *hashMap1, HashMap *hashMap2) { HashMap *pHashMap = createHashMap(hashMap1->capacity + hashMap2->capacity); HashMapIterator *pIterator1 = createHashMapIterator(hashMap1); while (hasNextHashMapIterator(pIterator1)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator1); putHashMap(pHashMap, entry->key, entry->value); } HashMapIterator *pIterator2 = createHashMapIterator(hashMap2); while (hasNextHashMapIterator(pIterator2)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator2); putHashMap(pHashMap, entry->key, entry->value); } return pHashMap; } //差集,返回一個(gè)新的Map集合,返回hashMap2的差集 HashMap *differenceHashMap(HashMap *hashMap1, HashMap *hashMap2) { HashMap *pHashMap = createHashMap(hashMap1->capacity); HashMapIterator *pIterator1 = createHashMapIterator(hashMap1); while (hasNextHashMapIterator(pIterator1)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator1); if (!containsKey(hashMap2, entry->key)) { putHashMap(pHashMap, entry->key, entry->value); } } return pHashMap; } //交集,返回一個(gè)新的Map集合 HashMap *intersectionHashMap(HashMap *hashMap1, HashMap *hashMap2) { HashMap *pHashMap = createHashMap(hashMap1->capacity); HashMapIterator *pIterator1 = createHashMapIterator(hashMap1); while (hasNextHashMapIterator(pIterator1)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator1); if (containsKey(hashMap2, entry->key)) { putHashMap(pHashMap, entry->key, entry->value); } } return pHashMap; } //補(bǔ)集,返回一個(gè)新的Map集合 HashMap *complementHashMap(HashMap *hashMap1, HashMap *hashMap2) { HashMap *pHashMap = createHashMap(hashMap1->capacity); HashMapIterator *pIterator1 = createHashMapIterator(hashMap1); while (hasNextHashMapIterator(pIterator1)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator1); if (!containsKey(hashMap2, entry->key)) { putHashMap(pHashMap, entry->key, entry->value); } } HashMapIterator *pIterator2 = createHashMapIterator(hashMap2); while (hasNextHashMapIterator(pIterator2)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator2); if (!containsKey(hashMap1, entry->key)) { putHashMap(pHashMap, entry->key, entry->value); } } return pHashMap; } //并集,返回一個(gè)新的Map集合 (如果有相同的key,則取hashMap2的值) HashMap *unionHashMap(HashMap *hashMap1, HashMap *hashMap2) { HashMap *pHashMap = createHashMap(hashMap1->capacity + hashMap2->capacity); HashMapIterator *pIterator1 = createHashMapIterator(hashMap1); while (hasNextHashMapIterator(pIterator1)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator1); putHashMap(pHashMap, entry->key, entry->value); } HashMapIterator *pIterator2 = createHashMapIterator(hashMap2); while (hasNextHashMapIterator(pIterator2)) { CharKvLinkedNode *entry = nextHashMapIterator(pIterator2); putHashMap(pHashMap, entry->key, entry->value); } return pHashMap; } void hashMapClear(HashMap *hashMap) { for (int i = 0; i < hashMap->nodeLen; i++) { // 釋放沖突值內(nèi)存 LinkedKvAndRbTree *pTree = hashMap->list[i]; if (pTree != NULL) { destroyLinkedKvAndRbTree(pTree); } } // 釋放存儲(chǔ)空間 free(hashMap->list); free(hashMap); }
使用
int main() { HashMap *pMap = createHashMap(10); for (int i = 0; i < 100; i++) { //插入從0~1億數(shù)據(jù)大約60~90秒 char *str = (char *) malloc(sizeof(char) * 10); sprintf(str, "%d", i); putHashMap(pMap, str, str); } //打印 printHashMap(pMap); //迭代器 // HashMapIterator *pIterator = createHashMapIterator(pMap); // while (hasNextHashMapIterator(pIterator)) { // CharKvLinkedNode *entry = nextHashMapIterator(pIterator); // printf("%s %s\n", entry->key, entry->value); // } // void *pVoid = getHashMap(pMap, "999999"); // O(1) 查詢速度 // printf("=====%s\n",pVoid); // CharList *pCharlist = getValues(pMap); // printCharList(pCharlist); hashMapClear(pMap); }
以上就是C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù))的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言 Map的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)三子棋游戲的示例代碼
今天我們將會(huì)用C語(yǔ)言實(shí)現(xiàn)三子棋。所謂三子棋,就是三行三列的棋盤(pán),玩家可以和電腦下棋,率先連成三個(gè)的獲勝。話不多說(shuō),我們開(kāi)始吧2022-10-10C語(yǔ)言代碼實(shí)現(xiàn)簡(jiǎn)單的掃雷小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言代碼實(shí)現(xiàn)簡(jiǎn)單的掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03C++實(shí)現(xiàn)航空訂票系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)航空訂票系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解
這篇文章主要介紹了C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解的相關(guān)資料,需要的朋友可以參考下2023-01-01淺析c#中如何在form的webbrowser控件中獲得鼠標(biāo)坐標(biāo)
以下是對(duì)c#中如何在form的webbrowser控件中獲得鼠標(biāo)坐標(biāo)的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下2013-07-07C語(yǔ)言課程設(shè)計(jì)之抽獎(jiǎng)系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言課程設(shè)計(jì)之抽獎(jiǎng)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12C++中?‘=default?’及‘?=delete?’的使用
這篇文章主要介紹了C++中?=default?及?=delete?使用,使用=default和=delete可以控制編譯器默認(rèn)函數(shù)體的使用,下面我們就來(lái)看看具體的室友方法吧,需要的朋友也可以參考一下2021-12-12VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法(注冊(cè)表修改)
這篇文章主要介紹了VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法,涉及VC++針對(duì)注冊(cè)表的相關(guān)操作技巧,需要的朋友可以參考下2016-08-08C語(yǔ)言中你不知道的隱式類(lèi)型轉(zhuǎn)換規(guī)則詳解
在C語(yǔ)言中,類(lèi)型轉(zhuǎn)換的方式一般可分為隱式類(lèi)型轉(zhuǎn)換和顯示類(lèi)型轉(zhuǎn)換(也稱為強(qiáng)制類(lèi)型轉(zhuǎn)換),其中隱式類(lèi)型轉(zhuǎn)換由編譯器自動(dòng)進(jìn)行,不需要程序員干預(yù),本文給大家詳細(xì)介紹了C語(yǔ)言中隱式類(lèi)型轉(zhuǎn)換規(guī)則,需要的朋友可以參考下2024-01-01C++文件的數(shù)據(jù)寫(xiě)入和文件的數(shù)據(jù)讀取的方法實(shí)現(xiàn)
本文主要介紹了C++文件的數(shù)據(jù)寫(xiě)入和文件的數(shù)據(jù)讀取的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06