<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      哈希表的C實現(二)

      上次大致分析了一下哈希表的鏈地址法的實現,今天來分析一下另一種解決哈希沖突的做法,即為每個Hash值,建立一個Hash桶(Bucket),桶的容量是固定的,也就是只能處理固定次數的沖突,如1048576個Hash桶,每個桶中有4個表項(Entry),總計4M個表項。其實這兩種的實現思路雷同,就是對Hash表中每個Hash值建立一個沖突表,即將沖突的幾個記錄以表的形式存儲在其中;

      廢話不多說,上代碼和圖示基本能說明清楚:

      完整的代碼,請看:這里,一位圣安德魯斯大學的講師:KRISTENSSON博客

      這里截取幾個主要的片段:

      主要的數據結構:

      struct Pair {
      char *key;
      char *value;
      };

      struct Bucket {
      unsigned int count;
      Pair *pairs;
      };

      struct StrMap {
      unsigned int count;
      Bucket *buckets;
      };

       

      主要的函數:

      put:

      int sm_put(StrMap *map, const char *key, const char *value)
      {
      unsigned int key_len, value_len, index;
      Bucket *bucket;
      Pair *tmp_pairs, *pair;
      char *tmp_value;
      char *new_key, *new_value;

      if (map == NULL) {
      return 0;
      }
      if (key == NULL || value == NULL) {
      return 0;
      }
      key_len = strlen(key);
      value_len = strlen(value);
      /* Get a pointer to the bucket the key string hashes to */
      index = hash(key) % map->count;
      bucket = &(map->buckets[index]);
      /* Check if we can handle insertion by simply replacing
      * an existing value in a key-value pair in the bucket.
      */
      if ((pair = get_pair(bucket, key)) != NULL) {
      /* The bucket contains a pair that matches the provided key,
      * change the value for that pair to the new value.
      */
      if (strlen(pair->value) < value_len) {
      /* If the new value is larger than the old value, re-allocate
      * space for the new larger value.
      */
      tmp_value = realloc(pair->value, (value_len + 1) * sizeof(char));
      if (tmp_value == NULL) {
      return 0;
      }
      pair->value = tmp_value;
      }
      /* Copy the new value into the pair that matches the key */
      strcpy(pair->value, value);
      return 1;
      }
      /* Allocate space for a new key and value */
      new_key = malloc((key_len + 1) * sizeof(char));
      if (new_key == NULL) {
      return 0;
      }
      new_value = malloc((value_len + 1) * sizeof(char));
      if (new_value == NULL) {
      free(new_key);
      return 0;
      }
      /* Create a key-value pair */
      if (bucket->count == 0) {
      /* The bucket is empty, lazily allocate space for a single
      * key-value pair.
      */
      bucket->pairs = malloc(sizeof(Pair));
      if (bucket->pairs == NULL) {
      free(new_key);
      free(new_value);
      return 0;
      }
      bucket->count = 1;
      }
      else {
      /* The bucket wasn't empty but no pair existed that matches the provided
      * key, so create a new key-value pair.
      */
      tmp_pairs = realloc(bucket->pairs, (bucket->count + 1) * sizeof(Pair));
      if (tmp_pairs == NULL) {
      free(new_key);
      free(new_value);
      return 0;
      }
      bucket->pairs = tmp_pairs;
      bucket->count++;
      }
      /* Get the last pair in the chain for the bucket */
      pair = &(bucket->pairs[bucket->count - 1]);
      pair->key = new_key;
      pair->value = new_value;
      /* Copy the key and its value into the key-value pair */
      strcpy(pair->key, key);
      strcpy(pair->value, value);
      return 1;
      }

      get:

      int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf)
      {
      unsigned int index;
      Bucket *bucket;
      Pair *pair;

      if (map == NULL) {
      return 0;
      }
      if (key == NULL) {
      return 0;
      }
      index = hash(key) % map->count;
      bucket = &(map->buckets[index]);
      pair = get_pair(bucket, key);
      if (pair == NULL) {
      return 0;
      }
      if (out_buf == NULL && n_out_buf == 0) {
      return strlen(pair->value) + 1;
      }
      if (out_buf == NULL) {
      return 0;
      }
      if (strlen(pair->value) >= n_out_buf) {
      return 0;
      }
      strcpy(out_buf, pair->value);
      return 1;
      }

      哈希函數:

      /*
      * Returns a hash code for the provided string.
      */
      static unsigned long hash(const char *str)
      {
      unsigned long hash = 5381;
      int c;

      while (c = *str++) {
      hash = ((hash << 5) + hash) + c;
      }
      return hash;
      }

      大致的思路是這樣的:


      首先哈希桶的個數是固定的,有用戶構建的時候輸入,一旦構建,個數就已經固定;查找的時候首先將key值通過哈希函數獲取哈希值,根據哈希值獲取到對應的哈希桶,然后遍歷哈希桶內的pairs數組獲取;


      這兩種實現方法看似比較類似,但也有差異:

      基于哈希桶的情況下,由于Hash桶容量的限制,所以,有可能發生Hash表填不滿的情況,也就是,雖然Hash表里面還有空位,但是新建的表項由于沖突過多,而不能裝入Hash表中。不過,這樣的實現也有其好處,就是查表的最大開銷是可以確定的,因為最多處理的沖突數是確定的,所以算法的時間復雜度為O(1)+O(m),其中m為Hash桶容量。

      而另一種通過鏈表的實現,由于Hash桶的容量是無限的,因此,只要沒有超出Hash表的最大容量,就能夠容納新建的表項。但是,一旦發生了Hash沖突嚴重的情況,就會造成Hash桶的鏈表過長,大大降低查找效率。在最壞的情況下,時間復雜度退化為O(n),其中n為Hash表的總容量。當然,這種情況的概率小之又小,幾乎是可以忽略的。


      后面我們再看看一些優秀的開源項目中是如何實現的;

      未完待續...

      posted @ 2012-01-16 11:06  紅心李  閱讀(8769)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 好男人社区影视在线WWW| 精品国产女同疯狂摩擦2| 亚洲一区二区约美女探花| 国产AV影片麻豆精品传媒| AV教师一区高清| 国产三级a三级三级| 黄色A级国产免费大片视频| 色综合天天色综合久久网| 国产黄色免费看| 人妻蜜臀久久av不卡| 中文字幕无码免费不卡视频| 真实国产乱子伦视频| 久久亚洲欧美日本精品| 堆龙德庆县| 精品国产中文字幕在线看| 亚洲欧洲日产国码AV天堂偷窥| 双乳奶水饱满少妇呻吟免费看| 久久亚洲国产五月综合网| 丁香五月亚洲综合在线国内自拍| 国产情侣激情在线对白| 四虎成人精品无码| 人妻放荡乱h文| 免费国产高清在线精品一区| 视频免费完整版在线播放| 狠狠躁夜夜躁无码中文字幕| 国产69精品久久久久乱码免费| 中文午夜乱理片无码| 国产精品久久久天天影视| 丁香婷婷在线观看| 国产精品久久久久久无毒不卡 | 四虎国产精品永久免费网址| 亚洲成av人片无码天堂下载| 激情一区二区三区成人文| 国产自产av一区二区三区性色| 浪潮av色综合久久天堂| 精品一区二区亚洲国产| 波多野结衣无内裤护士| 一区二区三区国产亚洲自拍| 亚洲va中文字幕无码久久不卡| 伊人久久大香线蕉AV网禁呦| 成人无码精品免费视频在线观看|