当前位置: 首页 > news >正文

C语言-手写Map(数组+链表+红黑树)(全功能)

要求

  1. 需要准备数组集合(List) 数据结构
  2. 需要准备单向链表(Linked) 数据结构
  3. 需要准备红黑树(Rbtree)数据结构
  4. 需要准备红黑树和链表适配策略(文章内部提供,可以自行参考)

建议先去阅读我博客这篇文章C语言-手写Map(数组+链表)(全功能) 有助于理解

在这里插入图片描述
hashmap使用红黑树的原因是: 当某个节点值过多的时候那么链表就会非常长,这样搜索的时候查询速度就是O(N) 线性查询了,为了避免这个问题我们使用了红黑树,当链表长度大于8的时候我们转换为红黑树,当红黑树的长度小于6的时候转换为链表,这样既可以利用链表对内存的使用率而且还可以使用红黑树的高效检索,是一种很有效率的数据结构。那么为啥不使用AVL树呢? 因为AVL树是一种高度平衡的二叉树,所以查找的非常高,但是,有利就有弊,AVL树为了维持这种高度的平衡,就要付出更多代价。每次插入、删除都要做调整,复杂、耗时。所以,使用红黑树是最好的策略。

结构

在这里插入图片描述

红黑树和链表转换策略

typedef int boolean;//定义一个布尔类型
#define TRUE 1
#define FALSE 0
enum LINKEDKV_RBTREE_TYPE{LINKEDKV=0,RBTREE=1};
typedef  struct  linkedKvAndRbTree{
    CharKvLinked *linked; // 链表
    RBTree *rbTree; // 红黑树
    int len;// 长度
    enum LINKEDKV_RBTREE_TYPE type; // 类型
} 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);
// 迭代器结构
typedef struct linkedKvAndRbTreeIterator {
    CharKvLinkedNode *next;// 迭代器当前指向
    int count;//迭代次数
    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>
//创建
LinkedKvAndRbTree *createLinkedKvAndRbTree() {
    LinkedKvAndRbTree *linkedKvAndRbTree= malloc(sizeof(LinkedKvAndRbTree));
    linkedKvAndRbTree->linked=NULL;
    linkedKvAndRbTree->rbTree=NULL;
    linkedKvAndRbTree->len=0;
    linkedKvAndRbTree->type=LINKEDKV;//默认是链表,满足条件则转换为红黑树或者降级为链表
    return linkedKvAndRbTree;
}

void linked_to_rbtree(LinkedKvAndRbTree *linkedKvAndRbTree){
    //链表转换为红黑树(不保证唯一性(可重复),自行判断)
    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;
    }
}
//红黑树转换为链表(不保证唯一性(可重复),自行判断)
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;
        //清除红黑树
        destroyRbTree(linkedKvAndRbTree->rbTree);
        linkedKvAndRbTree->rbTree=NULL;
    }
}

//插入时候key是唯一的,如果冲突那么就修改value
void insertOrUpdateLinkedKvAndRbTree(LinkedKvAndRbTree *linkedKvAndRbTree,char *key,char *value){
    if(linkedKvAndRbTree == NULL){
        return;
    }
    if(isLinked(linkedKvAndRbTree)){
        if(linkedKvAndRbTree->linked==NULL){
            linkedKvAndRbTree->linked= createCharKvLinked();
        }
        //长度大于8的时候转换为红黑树
        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++;
}
//查询,返回节点的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)){
        //长度小于6的时候转换为链表
        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;
    }
}
//销毁
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;//迭代次数
    linkedKvAndRbTreeIterator->linked = getAllLinkedKvAndRbTree(linkedKvAndRbTree);
    linkedKvAndRbTreeIterator->next = linkedKvAndRbTreeIterator->linked->head;//下次迭代节点
    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;//切换到下一个节点
    linkedKvAndRbTreeIterator->count++;
    return pNode;
}



hash

#ifndef STUDY_CHARHASH_H
#define STUDY_CHARHASH_H
#include "charlist.h"

#include "../structure/linkedKvAndRbTree.h"

typedef int boolean;//定义一个布尔类型
#define TRUE 1
#define FALSE 0
// 哈希表结构体
typedef struct hashMap {
    int size;           // 集合元素个数
    int capacity;       // 容量
    int nodeLen;       //节点长度
    LinkedKvAndRbTree **list;         // 存储区域
    int dilatationCount;  //扩容次数
    int dilatationSum;  //扩容总次数

} 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);



// 迭代器结构
typedef struct hashMapIterator {
    LinkedKvAndRbTreeIterator *linkedKvAndRbTreeIterator;// 迭代器
    CharKvLinkedNode *next;// 下次的值
    int count;//迭代次数
    HashMap *hashMap;
    int index; //位置
}HashMapIterator;
// 创建哈希结构迭代器
HashMapIterator *createHashMapIterator(HashMap *hashMap);
// 迭代器是否有下一个
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类型的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值长度取模最后获取实际位置的下标
static unsigned int defaultHashCode(HashMap hashMap, char *key) {
    return BKDRHash(key) % hashMap.capacity;
}

// 创建Map集合
HashMap *createHashMap(int capacity) {
    //创建哈希表
    HashMap *hashMap = (HashMap *) malloc(sizeof(HashMap));
    //创建存储区域
    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;
}

//扩容基数
static int expansionBase(HashMap *hashMap) {
    int len = hashMap->capacity;
    int dilatationCount = hashMap->dilatationCount;
    hashMap->dilatationSum++;
    //基础扩容
    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++;
    //频率扩容
    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;
}

//扩容Map集合
static void dilatationHash(HashMap *hashMap) {
    //原来的容量
    int capacity = hashMap->capacity;
    //扩容后的容量
    hashMap->capacity = expansionBase(hashMap);
    //节点长度清空
    hashMap->nodeLen = 0;
    //创建新的存储区域
    LinkedKvAndRbTree **newList = (LinkedKvAndRbTree **) calloc(hashMap->capacity, sizeof(LinkedKvAndRbTree));

    for (int i = 0; i < capacity; ++i) {
        //获取旧的存储区域的每个节点
        LinkedKvAndRbTree *node = hashMap->list[i];
        //如果节点不为空,将旧的节点所有数据放入新的存储区域
        if (node != NULL) {
            //拿到旧节点的所有key和value
            CharKvLinked *pCharKvLinked = getAllLinkedKvAndRbTree(node);
            //遍历每个key和value,将每个key和value放入新的存储区域
            CharKvLinkedIterator *pIterator = createCharKvLinkedIterator(pCharKvLinked);
            while (hasNextCharKvLinkedIterator(pIterator)) {
                CharKvLinkedNode *pNode = nextCharKvLinkedIterator(pIterator);
                //获取新的存储区域的下标
                unsigned int index = defaultHashCode(*hashMap, pNode->key);
                //将旧的节点放入新的存储区域
                LinkedKvAndRbTree *linkedKvAndRbTree = newList[index];
                if (linkedKvAndRbTree == NULL) {
                    //如果新存储区域的节点为空,创建新的节点
                    LinkedKvAndRbTree *newLinkedKvAndRbTree = createLinkedKvAndRbTree();
                    insertOrUpdateLinkedKvAndRbTree(newLinkedKvAndRbTree, pNode->key, pNode->value);
                    newList[index] = newLinkedKvAndRbTree;
                    hashMap->nodeLen++; //节点长度加1
                } else {
                    //如果新存储区域的节点不为空,将旧的节点放入新的存储区域
                    insertOrUpdateLinkedKvAndRbTree(linkedKvAndRbTree, pNode->key, pNode->value);
                }

            }
        }
    }

    //释放旧的存储区域
    free(hashMap->list);
    //将新的存储区域赋值给旧的存储区域
    hashMap->list = newList;
}

//给Map集合添加元素
void putHashMap(HashMap *hashMap, char *key, void *value) {
    //判断是否需要扩容
    if (hashMap->nodeLen == hashMap->capacity) {
        dilatationHash(hashMap);
    }
    //获取hash值
    unsigned int hashCode = defaultHashCode(*hashMap, key);
    //获取节点
    LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode];
    //如果节点是空的那么直接添加
    if (linkedKvAndRbTree == NULL) {
        //如果新存储区域的节点为空,创建新的节点
        LinkedKvAndRbTree *newLinkedKvAndRbTree = createLinkedKvAndRbTree();
        insertOrUpdateLinkedKvAndRbTree(newLinkedKvAndRbTree, key, value);
        hashMap->list[hashCode] = newLinkedKvAndRbTree;
        hashMap->size++;
        hashMap->nodeLen++;
        return;
    }
    //如果节点不为空,那么就插入或者修改
    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);
    //获取节点
    LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode];
    //如果节点是空的那么直接返回
    if (linkedKvAndRbTree == NULL) {
        return NULL;
    }
    //获取节点中的值
    return searchLinkedKvAndRbTree(linkedKvAndRbTree, key);
}

//判断键是否存在
boolean containsKey(HashMap *hashMap, char *key) {
    //获取hash值
    unsigned int hashCode = defaultHashCode(*hashMap, key);
    //获取节点
    LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode];
    //如果节点是空的那么直接返回FALSE
    if (linkedKvAndRbTree == NULL) {
        return FALSE;
    }
    return isExistLinkedKvAndRbTree(linkedKvAndRbTree, key);
}

//删除Map集合中的元素
void removeHashMap(HashMap *hashMap, char *key) {
    //获取hash值
    unsigned int hashCode = defaultHashCode(*hashMap, key);
    //获取节点
    LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode];
    //如果节点是空的那么直接返回
    if (linkedKvAndRbTree == NULL) {
        return;
    }
    //判断是否存在该键,并且一样的话,删除该节点
    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);
    //获取节点
    LinkedKvAndRbTree *linkedKvAndRbTree = hashMap->list[hashCode];
    //如果节点是空的那么直接返回
    if (linkedKvAndRbTree == NULL) {
        return;
    }
    //判断是否存在该键,然后进行修改
    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];
    //找到不是空的节点
    while (pTree == NULL) {
        pTree = hashMap->list[++pVoid->index];
    }
    //创建迭代器
    pVoid->linkedKvAndRbTreeIterator = createLinkedKvAndRbTreeIterator(pTree);
    //获取迭代器中的第一个节点
    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;
    //获取下一个节点
    CharKvLinkedNode *nextNode = nextLinkedKvAndRbTreeIterator(iterator->linkedKvAndRbTreeIterator);
    if (nextNode != NULL) {
        iterator->next = nextNode;
    } else {
        //如果是最后一个节点了,那么就不在找下个节点了
        if (iterator->count + 1 < iterator->hashMap->size) {
            //获取下一个节点
            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 ,返回一个自定义的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,返回一个自定义的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;
}

//复制一个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;
}

//将一个map集合,合并到另一个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);
    }
}

//合并两个Map集合,返回一个新的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;
}

//差集,返回一个新的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;
}

//交集,返回一个新的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;
}

//补集,返回一个新的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;
}

//并集,返回一个新的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++) {
        // 释放冲突值内存
        LinkedKvAndRbTree *pTree = hashMap->list[i];
        if (pTree != NULL) {
            destroyLinkedKvAndRbTree(pTree);
        }
    }
    // 释放存储空间
    free(hashMap->list);
    free(hashMap);
}

使用

int main() {

    HashMap *pMap = createHashMap(10);
    for (int i = 0; i < 100; i++) {  //插入从0~1亿数据大约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);


}

在这里插入图片描述

点赞 -收藏-关注-便于以后复习和收到最新内容
有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
在本博客学习的技术不得以任何方式直接或者间接的从事违反中华人民共和国法律,内容仅供学习、交流与参考
免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我、以迅速采取适当措施,避免给双方造成不必要的经济损失。
感谢,配合,希望我的努力对你有帮助^_^

相关文章:

  • 雅思写作课程 band 7+1
  • 人工智能畅想——《人工智能简史》读后感
  • Python 和 Selenium – 用于数据科学的爬虫教程
  • 在虚拟机上使用SoftRoCE部署SPDK NVMe-oF
  • ListMap集合
  • 分享一个查题公众号系统平台 好用且简单
  • WebWall-10.Over Permisson(越权漏洞)
  • 搜题系统平台 公众号查题必用
  • Linux(七)DNS域名解析服务器学习
  • c++基础(八)——静态成员
  • 【手把手带你学JavaSE系列】练习项目—图书管理系统
  • iptables实战
  • JavaScript心得笔记-1(后端了解必备)
  • 前端培训丁鹿学堂:css布局之定位知识总结
  • 基础 | 并发编程 - [AQS]
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • Mocha测试初探
  • Redis在Web项目中的应用与实践
  • session共享问题解决方案
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Spring核心 Bean的高级装配
  • Vultr 教程目录
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 老板让我十分钟上手nx-admin
  • 面试总结JavaScript篇
  • 什么是Javascript函数节流?
  • 微信小程序开发问题汇总
  • 一个JAVA程序员成长之路分享
  • 应用生命周期终极 DevOps 工具包
  • 原生js练习题---第五课
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • ionic异常记录
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # centos7下FFmpeg环境部署记录
  • #预处理和函数的对比以及条件编译
  • $.each()与$(selector).each()
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (2.2w字)前端单元测试之Jest详解篇
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (二)c52学习之旅-简单了解单片机
  • (论文阅读11/100)Fast R-CNN
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转) ns2/nam与nam实现相关的文件
  • (转)【Hibernate总结系列】使用举例
  • (转)四层和七层负载均衡的区别
  • (转载)(官方)UE4--图像编程----着色器开发
  • ./configure、make、make install 命令
  • .chm格式文件如何阅读
  • .net 7 上传文件踩坑
  • .Net Core webapi RestFul 统一接口数据返回格式