インタビューは尋ねなければなりません:細断されたハッシュテーブル

1.ハッシュテーブルを細断しますか?

ハッシュテーブルには、挿入、削除、および包含操作が含まれます。
挿入操作を例にとると、ティアリングプロセスは主に次のステップに分けられます
。1。挿入されたオブジェクトをint型に変換
、hashCode()関数を呼び出します。2。に変換ます。正当な添え字(ハッシュ関数:hash(key)= key%capacity)、例:int index = hashValue%array.length;
3.インデックス位置でリンクされたリストをトラバースして、キーが要素4にあるかどうかを判別します
。 Putキーはノードにインストールされ、対応するリンクリストに挿入されます
。5 要素数を
維持します。6...負荷率を維持することにより、より低い負荷率が維持されます。

これらの6つのステップは不可欠です。インタビュー中の主な目的は、これらの6つのステップを自分で正確に説明することです。これらの6つのステップを念頭に置くと、コードの記述が簡単になります。

第二に、引き裂きプロセス

1.挿入

挿入プロセスは上記の6つのステップであり、主に元のリンクリスト要素の直接展開に注意を払う必要があります。展開方法については後で詳しく説明します。

public class MyHashTable {
    
    
    //实现一个HashTable首先需要一个数组
    private Node[] array=new Node[11];
    //维护哈希表中所有元素的个数
    private int size;

    //插入操作
    public boolean insert(Integer key){
    
    
        //1.把对象转为int类型
        int hashValue=key.hashCode();


        //2.把hashValue转成合法的下标
        int index=hashValue%array.length;

        //3.遍历index位置处的链表,确定key在不在元素中
        Node current=array[index];
        while(current!=null){
    
    
            if(key.equals(current.key)){
    
    
                return false;
            }

            current=current.next;
        }


        //4.把key装进结点中,并插入到对应的链表中
        Node node=new Node(key);
        node.next=array[index];
        array[index]=node;

        //5.维护元素的个数
        size++;

        //6.通过维护负载因子,进而维护较低的负载因子
        if(size/array.length*100>75){
    
    
            dilatation();
        }
        return true;
    }

2.削除

削除プロセスには、上記の6つのステップも含まれます。違いは、削除する要素の先行ノードも定義されることです。エラーが発生しやすいポイントは、prevがnullの場合、ヘッドノードが削除され、このステップを削除できないことです。無視されます。

 public boolean  remove(Integer key){
    
    
        //1.采用hashCode转为int类型
        int hashValue=key.hashCode();

        //2.得到合法的下标
        int index=hashValue%array.length;

        Node prev=null;
        Node current=array[index];
        while(current!=null){
    
    
            //删除操作
            if(key.equals(current.key)){
    
    
                if(prev!=null){
    
    
                    prev.next=current.next;
                }else{
    
    
                    //prev为null,删除的是头节点
                    array[index]=current.next;
                }
                size--;
                return true;

            }
            prev=current;
            current=current.next;

            }
        return false;

    }

3.含める

public boolean contains(Integer key){
    
    
        int hashValue=key.hashCode();
        int index=hashValue%array.length;
        Node current=array[index];
        while(current!=null){
    
    
            if(key.equals(current.key)){
    
    
                return true;
            }
            current=current.next;
        }
        return false;

    }

4.拡張

容量を拡張する場合、元の要素を新しい配列に移動する必要がありますが、保存された要素のインデックスが配列の長さに関連し、配列の長さが変化するため、元のリンクリストに従って移動することはできません。 、インデックスも変更されるため、再計算する必要があります。各要素の添え字。

public void dilatation(){
    
    
        Node[] newArray=new Node[array.length*2];
   
        for(int i=0;i<array.length;i++){
    
    
            Node current=array[i];
            while (current!=null){
    
    
                Integer key=current.key;
                int hashValue=key.hashCode();
                int index=hashValue%newArray.length;
                //头插
                Node node=new Node(key);
                node.next=newArray[index];
                newArray[index]=node;

                current=current.next;

            }
        }
        array=newArray;
    }

おすすめ

転載: blog.csdn.net/m0_46551861/article/details/109632979