xiao_e

java算法01 - 链表

1、链表

在Java中实现链表,每个节点都有一个值,然后把它链接到下一个节点。下面来看一下节点的实现

     class Node<E> {
        private E e;
        private Node<E> next = null;

        Node() {
        }

        Node(E e) {
            this.e = e;
        }

        public void setNext(Node<E> next) {
            this.next = next;
        }

        public Node<E> getNext() {
            return next;
        }

        public E getValue() {
            return e;
        }

        public void setValue(E e) {
            this.e = e;
        }
    }

 

单链表

有了节点,来实现一个简单的单链表

**
 * 单链表数据结构简单实现
 * 
 * @author jade
 *
 */
public class SingleLinkedList<E> {

    private Node<E> head = null; // 每个链表都存有一个空值的头结点。
    private Node<E> tail = null; // 链表的最后一个结点,尾结点。
    private int size = 0; // 当前链表中的节点数目。

    /** 
     * 建立一个空链表(建立其头结点)。 
     */  
    public SingleLinkedList() {  
        head = new Node<E>();  
        tail = head;  
    }

    /**
     * 在链表的尾部插入数据
     * @param e 待插入的数据          
     * @return
     */
    public boolean add(E e) {
        Node<E> node = new Node<E>(e); // 将要插入的值封装成一个节点。
        tail.setNext(node); // 将待插入结点放到尾结点的下一个结点。
        tail = tail.getNext(); // 将新增加的结点设为尾节点。
        ++size; // 链表大小增1。
        return true;
    }

    /**
     * 
     * @param index 待插入的位置
     * @param e  待插入的元素          
     * @return
     */
    public boolean add(int index, E e) {
        checkValidateIndex(index);
        Node<E> newNode = new Node<E>(e); 
        Node preNode = null;
        if (index > 0) {
            preNode = getNode(index - 1);
        }else{
            preNode = head;
        }
        newNode.setNext(preNode.getNext());
        preNode.setNext(newNode);
        return true;
    }    

    /**
     * 获取指定位置的结点的值
     * @param index  欲获取值的结点的下标        
     * @return
     */
    public E get(int index) {
        checkValidateIndex(index);
        Node<E> node = getNode(index);
        return node.getValue();
    }

    /**
     * 删除指定位置的结点
     * @param index   待删除结点的下标
     * @return
     */
    public boolean remove(int index) {
        Node<E> curNode = null;
        if (0 == index) {
            curNode = head.getNext();
            Node<E> nextNode = curNode.getNext();
            head.setNext(nextNode);
        } else {
            checkValidateIndex(index);
            curNode = getNode(index); // 获取待删除节点。
            Node<E> preNode = getNode(index - 1); // 获取待删除节点的前一个结点。
            preNode.setNext(curNode.getNext());
        }
        curNode.setNext(null); // 将待删除节点的下一结点置空。
        return true;
    }

    /**
     * 设置指定位置结点的值。
     * @param index 待设置值的结点的下标
     * @param e
     */
    public void set(int index, E e) {
        checkValidateIndex(index);
        Node<E> node = getNode(index);
        node.setValue(e);
    }
    
    /**
     * 获取指定位置的结点
     * @param index 获取结点的下标
     *            
     */
    private Node<E> getNode(int index) {
        checkValidateIndex(index);
        Node<E> node = head;
        for (int p = 0; p <= index; ++p) {
            node = node.getNext();
        }
        return node;
    }

    /**
     * 验证下标值是否合法,非法时抛出异常。
     * @param index 待验证的下标值
     * @throws Exception 
     *            
     */
    private void checkValidateIndex(int index) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("无效的下标:" + index);
        }
    }

    /**
     * 获取链表的大小。
     * @return
     */
    public int size() {
        return size;
    }

 

堆栈和队列是两种特殊的线性表,下面来看一下他们的链式实现

栈(Stack)

java中的Stack是继承Vector的 :public class Stack<E> extends Vector<E>

下面来看一下Stack的简单实现:

class Stack {
        Node top;

        /**
         * 栈顶元素
         * @return
         */
        public Node peek() {
            if (top != null) {
                return top;
            }
            return null;
        }
        
        /**
         * 退栈
         * @return
         */
        public Node pop() {
            if (top == null) {
                return null;
            } else {
                Node temp = new Node(top.next);
                top = top.next;
                return temp;
            }
        }

        /**
         * 入栈
         * @param n
         */
        public void push(Node n) {
            if (n != null) {
                n.next = top;
                top = n;
            }
        }
    }

 

队列(queue)

下面基于链表实现一个阻塞对列

/**
 * 基于链表实现的一个阻塞队列
 * 
 * @author jade
 *
 */
public class BlockingQueue {
    private int capacity ; // 阻塞队列容量
    private List queue = new LinkedList(); // 基于链表实现的一个阻塞队列

    public BlockingQueue() {
        this(Integer.MAX_VALUE);
    }

    public BlockingQueue(int capacity) {
        this.capacity = capacity;
    }

    /**
     * 入队列
     * 
     * @param item
     * @throws InterruptedException
     */
    public synchronized void enqueue(Object item) throws InterruptedException {
        while (this.queue.size() == this.capacity) {
            wait();
        }
        if (this.queue.size() == 0) {
            notifyAll();
        }
        this.queue.add(item);
    }

    /**
     * 出队列
     * 
     * @return
     * @throws InterruptedException
     */
    public synchronized Object dequeue() throws InterruptedException {
        while (this.queue.size() == 0) {
            wait();
        }
        if (this.queue.size() == this.capacity) {
            notifyAll();
        }
        return this.queue.remove(0);
    }

}

 

posted on 2017-04-20 14:40  xiao_e  阅读(182)  评论(0)    收藏  举报

导航