雜湊桶的本質是雜湊表,雜湊表的本質是 k-v,k-v 不就是 map,那麼這樣一層一層學習下來,就能理解的更為透徹,學習程式設計一定要有追根刨底的好奇心,這樣你的進步會非常快。
1、桶
就是可以存放資料的結構;在這裡我認為桶就是結構體!
在雜湊表的改進之上,雜湊表當時自己的做法是:表中存放的是指標,而不能存放資料;
現在用桶儲存:雜湊表中的每個元素是結構體,有資料域和鏈域!(根據自己的情況不同而進行規定存放資料的多少和相應的有幾個鏈域);其後雜湊結點也可以這樣定義,結點存放資料多少自己都可以定義;表中的結構體和結點的結構體沒有什麼聯絡!
在這我為了簡單起見,讓表中元素的結構體型別和鍊錶結點型別一致。
模型圖:
2、實際問題
現在就是有乙個存放整數的 hash 表,hash 表的儲存單位叫做桶,每個桶存放 3 個整數,當乙個桶中的元素超過 3 個時,要將新的元素存放在溢位桶中,每個溢位桶最多也只能放 3 個元素,多個溢位桶用鍊錶串起來,此 hash 表的基桶數目為 p,hash 表的 hash 函式為對 p 取模,初始化桶時,要求資料預設為 -1,指標為 null,要求**實現上述內容。
(1)、問題分析
hash 表的儲存單位叫做桶--->就是說 hash 表元素的資料型別是結構體。
結構體中有 3 個資料域和 1 個指標域,溢位桶的結構體型別和表元素型別一致;雜湊函式用的是除留餘數法。
這個問題的模型和上面的那個圖正好一一對應。
(2)、**實現
在這我只實現了初始化,插入,輸出的函式。
我把函式宣告和定義都寫在了 .h 檔案中,只是為了方便;宣告和定義本質上是應該分開寫的。
以下**都是純 c 寫的,與 c++ 沒有牽扯。
1#ifndef _bucket_hash_h_
2#define _bucket_hash_h_
34#include
56typedef unsigned char boolean;
78#define true 1
9#define false 0
1011#define p 7
12#define bucket_node_size 3
13#define null_data -1
1415//表和結點都是這個結構體型別
16typedef struct bucket_nodebucket_node;
2021typedef bucket_node hashtable[p];
2223int hash(elemtype key)
26//初始化雜湊表,只不過是桶的形式。
27void inithashtable(hashtable ht);
28boolean insertnewelement(hashtable ht, elemtype value);
29void showhashtable(hashtable ht);
3031void showhashtable(hashtable ht)
43 }
44 printf("-->");
45 p = ht[i].next;
46 while(p)
51 }
52 printf("-->");
53 p = p->next;
54 }
55 }
56 printf("null\n");
57 }
58}59boolean insertnewelement(hashtable ht, elemtype value)
71 }
72 p = &ht[index]; //取表中某元素的位址
73 q = p->next; //指向了第乙個結點,目的:儲存前驅結點,在新生成結點時方便連線。
74 while(q)
80 }
81 p = q; //p永遠儲存的是前驅結點
82 q = q->next;
83 }
8485 s = (bucket_node *)malloc(sizeof(bucket_node)); //此時,得生成新節點,用來存放資料
86 if(s == null)
89 for(i = 0; i //對新生成的結點進行初始化工作
90 s->data[i] = null_data; //這裡可以寫個函式提取出來
91 }
92 s->next = null;
93 s->data[0] = value; //新生成的結點,對其賦值
9495 p->next = s; //鏈域的連線。
9697 return true;
9899}
100void inithashtable(hashtable ht)
108 ht[i].next = null;
109 }
110}
111112#endif
(3)、測試**1#include
23typedef int elemtype;
45#include"buckethash.h"
67void main(void);
10 int n = sizeof(ar) / sizeof(int);
11 int i;
1213 inithashtable(ht);
14 for(i = 0; i 15 insertnewelement(ht, ar[i]);
16 }
1718 showhashtable(ht);
19}
(4)、測試結果
3、分析總結(1)、我自己認為插入函式(尾插)是重點。
思路:我們在插入資料時,首先考慮的是雜湊表中是否可以存放我們的資料;其次不是立馬開闢空間,而是判斷其後的鏈域空間是否可以存放;最後,就只能自己開闢空間,把資料存放到第乙個位置。
(2)、這個問題還遠遠沒有結束,還有好幾個方法沒有實現。
i>對新生成的結點進行前插;
ii>刪除某乙個資料,這個情況就比較多了,注意:刪除資料,其它的應該前移,不然造成空間的浪費,對於結點中沒有資料的應該釋放這個空間;
iii>查詢某乙個結點的位置,通過返回值和引數,乙個確定位址,乙個確定在陣列的下標;
iv>還有銷毀函式;
.....................
(3)、以空間換時間的查詢演算法,雜湊函式選取恰當,在較好的處理衝突的前提下,雜湊查詢的時間複雜度可以認為是o(1)。推薦閱讀:從零開始學習資料結構-->入門篇
從零開始學習資料結構-->鍊錶
從零開始學習資料結構-->線性表
從零開始學習資料結構-->棧
從零開始學習資料結構-->佇列
從零開始學習資料結構-->矩陣+串
從零開始學習資料結構-->雜湊表
認真的人 自帶光芒
從零開始學習react
react.createlement tag,content class shoppinglist extends react.component return 我們可以把兩者結合起來,使 react 的 state 成為 唯一資料來源 渲染表單的 react 元件還控制著使用者輸入過程中表單發生的...
C 從零開始學習
首先你需要乙個編譯器,在這裡我首先是推薦功能強大的visual studio最強ide。vs 可以嘗試自己在ide裡面敲一下,畢竟只有多動手才能成功!include 此為標頭檔案 using namespace std 告訴編譯器使用 std 命名空間。main方法為主函式,是程式開始執行的地方 i...
從零開始學習javascript(一)
從基礎開始吧,加油 表示和處理乙個html或xml文件的常用方法,可以歸類為介面,其實從個人看來也就是個定義格式的標準?層層巢狀的節點樹 由此衍生的各類呼叫方法。dom也是有分類噠,比如xml dom 用於獲取 更改 新增或刪除 xml 元素的標準 和html dom 關於如何獲取 修改 新增或刪除...