一:對以往所學的簡單數據結構回顧
學習程序語言時數組是我們首先接觸到的數據結構。衆所周知,數組在訪問數據時通過下標可以及其快速的訪問數據,但是在刪除和插入時數組就表現的並不優越。
鏈表在數據的刪除和插入時會很方便,但是不能達到對數據的快速訪問。
那麼有沒有一種對兩者進行綜合的數據結構呢?
答案是肯定的。比如Hash數據結構就可以即擁有數組的優點又可以實現鏈表的優點。
那麼我們就簡單的介紹一下什麼是Hash,並實現一個簡單的Hash結構
二:Hash的簡單介紹
Hash:Hash就是將任意長度的輸入通過散列算法得到固定長度的輸出,該輸出即爲散列值。
其中得到散列值的方法極爲散列函數。散列函數可以得到存儲元素的存儲位置。
例如:向數組中存入數據 200,如果直接將200作爲數組的元素值存儲(比如array[i]=200),則在查找的時候需要遍歷數組並判斷某一位置是否是200。
這樣的存儲方法在查找在數據比較多的時候會比較浪費時間。
那麼我們可以通過某一函數,獲得該元素所在位置的索引,那麼在查找的時候只需獲得該索引位置的數據即可。
比如:
int index = H(存入的元素);
其中index 即爲獲得的索引。而該函數即爲散列函數。
常用的構造散列函數的方法如下:
1:直接尋址法
2:數字分析法
3:平方取中法
4:摺疊法
5:隨機法
6:除留取餘法:取關鍵字被某個不大於散列表長度的數P除後所得的餘數爲散列地址。例如關鍵字200,取P=30;餘數20即爲關鍵字200的散列地址。
三:用除留取餘法實現一個簡單的Hash結構
聰明的你肯定會想到在做除留取餘時可能會出現具有相同散列地址的情況。
爲了處理這一問題我們就需要將數組和鏈表聯合使用了。
其中數組存儲鏈表,而鏈表存儲元素。
依然用除留取餘法獲得元素的索引,若有相同的散列地址則將該數據添加到該位置處鏈表中
那麼我們首先定義一個節點類
package hashV3;
public class DataNode { public int member; public DataNode next; }
定義一個鏈表並實現數據的添加和刪除
package hashV3; public class MyHash { private DataNode[] array = new DataNode[100]; private int getHash(DataNode node){ int index = node.member%10; return index; } /** * 添加元素 * @param node */ public void add(DataNode node){ int index = this.getHash(node); if(array[index] == null){ array[index] = node; }else{ node.next = array[index]; array[index] = node; System.out.println("====--->>>>"+node.member); } } public boolean remove(DataNode node){ int index = this.getHash(node); if(node == null || array[index]==null){ //如果刪除的數據爲空 return false; } DataNode temp = array[index]; if(temp.member==node.member){//如果刪除的是第一個數據 array[index] = temp.next; } while(temp.next.member != node.member && temp.next!=null){ temp = temp.next; } temp.next = temp.next.next; return true; } /** * 打印數據 */ public void print(){ for(int i=0; i<array.length; i++){ if(array[i]!= null){ DataNode node = array[i]; while(node != null){ System.out.println(" "+node.member); node = node.next; } } } } }
則在主函數中實現數據的添加和刪除
package hashV3; import java.util.Random; public class HashMain { public static void main(String[] args){ HashMain h = new HashMain(); h.add(); h.remove(); } /** * 添加方法 */ private void add(){ MyHash hash = new MyHash(); Random rand = new Random(); for(int i=0; i<10; i++){ int a = rand.nextInt(4); DataNode node = new DataNode(); node.member = a; hash.add(node); } hash.print(); } /** * 刪除方法 */ private void remove(){ MyHash hash = new MyHash(); DataNode n = new DataNode(); n.member = 2; hash.remove(n); System.out.println("************************************************"); hash.print(); } }