Java数据结构--HashTable(拉链法)

双向节点

/**
 * Created by root on 16-3-6.
 */
public class Node<E> {
    public E data;
    public Node prev;
    public Node next;
    public Node(E target,Node prev,Node next){//链接两个孤立节点
        data=target;
        this.prev=prev;
        this.next=next;
    }
    public Node(){
        this(null,null,null);
    }
    public Node(E target){
        this(target,null,null);
    }
}

双向链表 用于存储数据单元

/**
 * Created by root on 16-3-6.
 */
public class MyLinkedList<E> {
    private Node beginMaker;
    private Node endMaker;
    private int size;   //length

    public boolean isEmpty(){
        return beginMaker.next==endMaker;
    }
    public MyLinkedList() {  //Constructor
        beginMaker = new Node();
        endMaker = new Node(null, beginMaker, null);//链接beginMaker和endMaker
        beginMaker.next=endMaker;
        size = 0;
    }

    public MyLinkedList(int thatSize, E target) {  //Constructor
        this();
        size = thatSize;
        for (int i = 0; i < size; i++) {
            this.add(target);
        }
    }

    public void add(E target) {
        Node node = new Node(target, endMaker.prev, endMaker);//增加一个节点 要4步
        node.prev.next = node;
        endMaker.prev = node;
        size++;
    }

    public boolean contains(E target) {//双向搜索
        Node node = findNode(target);
        if (node != null) {
            return true;
        } else {
            return false;
        }
    }

    public boolean remove(E target) { //delete
        Node node = findNode(target);
        if (node != null) {
            node.prev.next = node.next;//把前节点和后节点链接
            node.next.prev = node.prev;
            size--;
            return true;
        }
        return false;
    }

    private Node findNode(E target) {//双向搜索
        Node node1 = beginMaker.next;
        Node node2 = endMaker.prev;
        if(isEmpty())return null;
        for (int i = 0; i <= size / 2; i++) {

            if (node1.data.equals(target)) {
                return node1;
            } else if (node2.data.equals(target)) {
                return node2;
            } else {
                node1 = node1.next;
                node2 = node2.prev;
            }
        }
        return null;
    }

    public Node getNode(int index) {//根据Index和 size/2 分类搜索
        if (index >= size) {
            throw new IndexOutOfBoundsException();
        } else if (index < size / 2) {
            Node node = beginMaker.next;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        } else {
            Node node = endMaker.prev;
            for (int i = size - 1; i > index; i--) {
                node = node.prev;
            }
            return node;
        }
    }

}

HashTable List 用于存放双向链表 构成一个十字链表

/**
 * Created by root on 16-3-6.
 */
public class HashTableList {
    public static class hNode {
        MyLinkedList data;
        hNode prev;
        hNode next;

        public hNode(MyLinkedList list, hNode prev, hNode next) {
            data = list;
            this.prev = prev;
            this.next = next;
        }
    }

    public hNode beginMaker;
    public hNode endMaker;
    public int size;

    public HashTableList() {
        beginMaker = new hNode(null, null, null);
        endMaker = new hNode(null, beginMaker, null);
        size = 0;
    }

    public HashTableList(int size) {
        this();
        for (int i = 0; i < size; i++) {
            this.add(new MyLinkedList());
        }
    }

    public void add(MyLinkedList target) {
        hNode node = new hNode(target, endMaker.prev, endMaker);
        node.prev.next = node;
        endMaker.prev = node;
        size++;
    }

    public hNode gethNode(int index) {//根据Index和 size/2 分类搜索
        if (index >= size) {
            throw new IndexOutOfBoundsException();
        } else if (index < size / 2) {
            hNode node = beginMaker.next;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        } else {
            hNode node = endMaker.prev;
            for (int i = size - 1; i > index; i--) {
                node = node.prev;
            }
            return node;
        }
    }

}

HashTable 用于增加 和 删除 以及查找

/**
 * Created by root on 16-3-6.
 */
public class HashTable<E> {
    HashTableList list;
    int size;

    public HashTable(int size) {
        list = new HashTableList(size);
        this.size = size;
    }

    public void insert(E target) {
        int hashVal = myHash(target);
        MyLinkedList myLinkedList = list.gethNode(hashVal).data;
        if (!myLinkedList.contains(target)) {
            myLinkedList.add(target);
        }
    }

    public boolean remove(E target) {
        int hashVal = myHash(target);
        MyLinkedList myLinkedList = list.gethNode(hashVal).data;
        return myLinkedList.remove(target);
    }

    public int myHash(E target) {
        int hashVal = target.hashCode();
        hashVal %= size;
        if (hashVal < 0) {
            hashVal += size;
        }
        return hashVal;
    }

    public int contains(E target) {
        int hashVal = myHash(target);
        MyLinkedList myLinkedList = list.gethNode(hashVal).data;
        if (myLinkedList.contains(target)) {
            return hashVal;
        } else {
            return -1;
        }
    }
}

测试类

/**
 * Created by root on 16-3-6.
 */
public class Test {
    public static void main(String[] args){
        HashTable hashTable=new HashTable(11) ;
        hashTable.insert(12);
        hashTable.insert("sjkljg");
        hashTable.insert(145);
        System.out.println(hashTable.contains(12));
        System.out.println(hashTable.contains(145));
        System.out.println(hashTable.contains("sjkljg"));
        hashTable.remove(12);
        System.out.println(hashTable.contains(12));
    }
}

输出结果

1
2
9
-1
posted @ 2016-03-06 14:59  Salaku  阅读(611)  评论(0编辑  收藏  举报