基于拉链法的散列表(来自:算法)

下列代码主要实现了基于拉链法的散列表的添加元素put(),查找元素get(),删除元素delete(),遍历元素keys()等方法,我们需要首先根据元素值调用hash()方法找到该元素所对应的数组,而每一个数组都是一个链表,遍历链表,若元素不存在,则可以实现元素的添加,若存在,则可以实现元素的更新,删除等操作.

对于每一条链表的操作

package cn.edu.zzuli.api;

import edu.princeton.cs.algs4.Queue;

public class SequentialSearchST<Key, Value> {
    private Node first;//链表首结点
	private class Node{
		//链表结点的定义
		private final Key key;
		private Value val;
		private Node next;
		
		public Node(Key key, Value val, Node next) {
			this.key = key;
			this.val = val;
			this.next = next;
		}
		public Key getKey() {
			return key;
		}

		public Value getVal() {
			return val;
		}

		public void setVal(Value val) {
			this.val = val;
		}

		public Node getNext() {
			return next;
		}

		public void setNext(Node next) {
			this.next = next;
		}
		
	}
	//查找给定的键,返回相关联的值
	public Value get(Key key) {
		for(Node i = first; i != null; i = i.next) {
            if(key.equals(i.key))
            	return i.val;
		}
		return null;
	}
	//查找给定的键,找到则更新其值,否则在表中新建结点
	public void put(Key key, Value val) {
		for(Node i = first; i != null; i = i.next) {
			if(key.equals(i.key)) {
				i.val = val;
				return;
			}
		}
		first = new Node(key, val, first);
	}
	//删除结点
	public void delete(Key key) {
		first = delete(first, key);
	}
	private Node delete(Node x, Key key) {
		if(x == null) {
			return null;
		}
		if(key.equals(x.key)) {
			return x.next;
		}
		x.next = delete(x.next, key);
		return x;
	}
	public Iterable<Key> keys(){
		Queue<Key> q = new Queue<Key>();
		for(Node i = first;  i != null; i = i.next) {
			q.enqueue(i.key);
		}
		return q;
	}
	public Key getKey() {
		return first.key;
	}
}

基于拉链法的散列表

package cn.edu.zzuli.api;

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdIn;

public class SeparateChainingHashST<Key, Value> {
	//SequetialSearchST
	private int N;//键值对总数
	private int M;//散列表的大小
	private SequentialSearchST<Key, Value>[] st;//存放链表对象的数组
    public SeparateChainingHashST() {//默认的构造函数会使用997条链表
    	this(997);
    }
    public SeparateChainingHashST(int M) {
    	//创建M条链表
    	this.M = M;
    	//创造一个(SequentialSearchST<Key, Value>[])类型的,长度为M的数组
    	st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[M];
    	for(int i = 0; i < M; i++) {
    		//为每一个数组元素申请一个空间
    		st[i] = new SequentialSearchST();
    	}
    }
    private int hash(Key key) {
    	return (key.hashCode() & 0x7fffffff) % M;
    }
    public Value get(Key key) {
    	return (Value)st[hash(key)].get(key);
    }
    public void put(Key key, Value val) {
    	st[hash(key)].put(key, val);
    }
    public void delete(Key key) {
    	st[hash(key)].delete(key);
    }
    public Iterable<Key> keys(){
    	Queue<Key> queue = new Queue<Key>();
    	for(int i = 0; i < M; i++) {
    		System.out.println("第" + i +"个元素的链表");
    		for(Key key : st[i].keys()) {
    			queue.enqueue(key);
    			System.out.print(key + " " + get(key) + " ,");
    		}
    		System.out.println();
    	}
    	return queue;
    }
    public static void main(String[] args) {
    	SeparateChainingHashST<String, Integer> st = new SeparateChainingHashST<String, Integer>(5);
        for (int i = 0; i < 13; i++) {
            String key = StdIn.readString();
            st.put(key, i);
        }
        for (String s : st.keys())
            StdOut.println(s + " " + st.get(s));
        st.delete("M");
        StdOut.println("*************************************");
        for (String s : st.keys()) {
        	 StdOut.println(s + " " + st.get(s));
        }
    }
}

测试用例

S E A R C H E X A M P L E

不同的机器的hashCode()不一定相同

阅读更多

没有更多推荐了,返回首页