代码改变世界

队列,链表及二叉查找树

2012-07-08 11:34  coodoing  阅读(296)  评论(0编辑  收藏  举报

Queue(链式队列)

Queue
package Queue;

class QNode<T> {
    T data;
    QNode<T> next;

    public boolean equals(QNode<T> node) {
        if (data.equals(node.data)) {
            return true;
        }
        return false;
    }

    public int hashCode() {
        return data.hashCode();
    }
}

class LinkQueue<T> {
    QNode<T> front;
    QNode<T> rear;
    int size;

    public LinkQueue() {

    }

    public void init() {
        front = new QNode<T>();
        rear = front;

        front.next = null;
        size = 0;
    }

    public void destroy() {

    }

    //插入队尾
    public void enQueue(T key) {
        QNode<T> node = new QNode<T>();
        node.next = null;
        node.data = key;

        // 队列为空时添加的node
        if (front.next == null) {
            front.next = node;
        }
        rear.next = node;//修改间接后继
        rear = node;//修改直接后继
    }

    //删除队头
    public QNode<T> deQueue() {
        QNode<T> node = new QNode<T>();
        if (!isEmpty()) {
            node = front.next;
            front.next = node.next;
            System.out.println("删除的value值为:" + node.data);

            //删除队列中最后一个元素的处理
            if (rear == node)
                rear = front;
            return node;
        }
        return null;
    }

    public boolean isEmpty() {
        if (front == rear)
            return true;
        return false;
    }

    public void queueTraverse() {
        if (isEmpty()) {
            System.out.print("当前队列为空");
        } else {
            //与双向列表有所区别
            QNode<T> node = front;
            while (node.next != null) {
                System.out.print(node.next.data + "-->");
                node = node.next;
            }
            System.out.println();
        }
    }
}

public class QueueTest {

    public static void main(String[] args) {
        LinkQueue<Integer> queue = new LinkQueue<Integer>();
        queue.init();
        /************************
         * 入队列操作
         * **********************/
        queue.enQueue(1);
        queue.enQueue(2);
        queue.enQueue(3);
        queue.enQueue(4);
        queue.queueTraverse();
        /************************
         * 出队列操作
         * **********************/
        queue.deQueue();
        queue.deQueue();
        queue.deQueue();
        queue.deQueue();
        queue.queueTraverse();
    }
}

Queue(顺序队列)

Queue2
package Queue;

//顺序队列
////////////////////////////////////////////////////////////////
class Queue {
    private int maxSize;
    private long[] queArray;
    private int front;
    private int rear;
    private int nItems;

    //--------------------------------------------------------------
    public Queue(int s) // constructor
    {
        maxSize = s;
        queArray = new long[maxSize];
        front = 0;
        rear = -1;
        nItems = 0;
    }

    //--------------------------------------------------------------
    public void insert(long j) // put item at rear of queue
    {
        if (rear == maxSize - 1) // deal with wraparound
            rear = -1;
        queArray[++rear] = j; // increment rear and insert
        nItems++; // one more item
    }

    //--------------------------------------------------------------
    public long remove() // take item from front of queue
    {
        long temp = queArray[front++]; // get value and incr front
        if (front == maxSize) // deal with wraparound
            front = 0;
        nItems--; // one less item
        return temp;
    }

    //--------------------------------------------------------------
    public long peekFront() // peek at front of queue
    {
        return queArray[front];
    }

    //--------------------------------------------------------------
    public boolean isEmpty() // true if queue is empty
    {
        return (nItems == 0);
    }

    //--------------------------------------------------------------
    public boolean isFull() // true if queue is full
    {
        return (nItems == maxSize);
    }

    //--------------------------------------------------------------
    public int size() // number of items in queue
    {
        return nItems;
    }
    //--------------------------------------------------------------
} // end class Queue
////////////////////////////////////////////////////////////////

public class QueueApp {
    public static void main(String[] args) {
        Queue theQueue = new Queue(5); // queue holds 5 items

        theQueue.insert(10); // insert 4 items
        theQueue.insert(20);
        theQueue.insert(30);
        theQueue.insert(40);

        theQueue.remove(); // remove 3 items
        theQueue.remove(); //    (10, 20, 30)
        theQueue.remove();

        theQueue.insert(50); // insert 4 more items
        theQueue.insert(60); //    (wraps around)
        theQueue.insert(70);
        theQueue.insert(80);

        while (!theQueue.isEmpty()) // remove and display
        { //    all items
            long n = theQueue.remove(); // (40, 50, 60, 70, 80)
            System.out.print(n);
            System.out.print(" ");
        }
        System.out.println("");
    } // end main()
} // end class QueueApp

二叉查找树(BST)

BSTree
package Tree;

//http://jiangzhengjun.iteye.com/blog/561590

//二叉查找树的节点类
class BSTreeNode {
    int data;//数据域
    BSTreeNode right;//左孩子
    BSTreeNode left;//右孩子

    //构造二叉查找树的节点
    public BSTreeNode(int data, BSTreeNode right, BSTreeNode left) {
        this.data = data;
        this.right = right;
        this.left = left;
    }

}

public class BSTree {
    BSTreeNode rootNode;// 创建根节点

    // 创建二叉查找树
    public void createBSTree(int[] A) {
        rootNode = new BSTreeNode(A[0], null, null);// 初始化根节点

        for (int i = 1; i < A.length; i++) {// 逐个取出数组A中的元素用来构造二叉查找树
            BSTreeNode tmpNode = rootNode;
            while (true) {
                if (tmpNode.data == A[i])
                    break;

                if (tmpNode.data > A[i]) {// 小于等于根节点
                    if (tmpNode.left == null) {// 如果左孩子为空,这把当前数组元素插入到左孩子节点的位置
                        tmpNode.left = new BSTreeNode(A[i], null, null);
                        break;
                    }
                    tmpNode = tmpNode.left;// 如果不为空的话,则把左孩子节点用来和当前数组元素作比较
                } else {// 大于根节点
                    if (tmpNode.right == null) {// 如果右孩子为空,这把当前数组元素插入到左孩子节点的位置
                        tmpNode.right = new BSTreeNode(A[i], null, null);
                        break;
                    }
                    tmpNode = tmpNode.right;// 如果不为空的话,则把右孩子节点用来和当前数组元素作比较
                }
            }
        }

    }

    // 中序遍历二叉查找树(中序遍历之后便可以排序成功)
    public void inOrderBSTree(BSTreeNode x) {
        if (x != null) {
            inOrderBSTree(x.left);// 先遍历左子树
            System.out.print(x.data + ",");// 打印中间节点
            inOrderBSTree(x.right);// 最后遍历右子树
        }
    }

    // 查询二叉排序树--递归算法
    public BSTreeNode searchBSTree1(BSTreeNode x, BSTreeNode k) {
        if (x == null || k.data == x.data) {
            return x;// 返回查询到的节点
        }
        if (k.data < x.data) {// 如果k小于当前节点的数据域
            return searchBSTree1(x.left, k);// 从左孩子节点继续遍历
        } else {// 如果k大于当前节点的数据域
            return searchBSTree1(x.right, k);// 从右孩子节点继续遍历
        }
    }

    // 查询二叉排序树--非递归算法
    public BSTreeNode searchBSTree2(BSTreeNode x, BSTreeNode k) {
        while (x != null && k.data != x.data) {
            if (x.data > k.data) {
                x = x.left;// 从左孩子节点继续遍历
            } else {
                x = x.right;// 从右孩子节点继续遍历
            }
        }
        return x;
    }

    // 查找二叉查找树的最小节点
    public BSTreeNode searchMinNode(BSTreeNode x) {
        while (x.left != null) {
            x = x.left;
        }
        return x;
    }

    // 查找二叉查找树的最大节点
    public BSTreeNode searchMaxNode(BSTreeNode x) {
        while (x.right != null) {
            x = x.right;
        }
        return x;
    }

    // 插入节点进入二叉查找树
    public void insert(BSTreeNode k) {
        BSTreeNode root = rootNode;
        //System.out.println("\n*****************");
        //System.out.println("rootNode=" + rootNode.data);

        while (true) {
            if (root.data == k.data)
                return;
            else if (root.data > k.data) {
                if (root.left == null) {
                    root.left = k;
                    break;
                }
                root = root.left;
            } else {
                if (root.right == null) {
                    root.right = k;
                    break;
                }
                root = root.right;
            }
        }
    }

    // 删除二叉查找树中指定的节点
    public void delete(BSTreeNode k) {// 分三种情况删除
        if (k.left == null && k.right == null) {// 第一种情况--没有子节点的情况下
            //System.out.println("#####没有子节点的情况");
            BSTreeNode p = parent(k);
            //System.out.println("父节点为:"+p.data+" "+p.left.data+" "+p.right.data);
            if (p.left == k) {// 其为父亲节点的左孩子
                p.left = null;
            } else if (p.right == k) {// 其为父亲节点的右孩子
                p.right = null;
            }
        } else if (k.left != null && k.right != null) {// 第二种情况--有两个孩子节点的情况下
            //System.out.println("\n#####左右子树不为空的情况");
            
            //由直接后继取代删除的节点
            BSTreeNode s = successor(k);// k的后继节点            
            delete(s);
            k.data = s.data;        //只是简单的data替换
            
            //BSTreeNode suc = successor(k); //后继
            //BSTreeNode pre = predecessor(k); //前驱
            //k.data = pre.data;            
            //BSTreeNode parent = parent(pre);
            //parent.right = pre.left;            
            //delete(pre);        
        } else {// 第三种情况--只有一个孩子节点的情况下
            //System.out.println("#####只有一个孩子节点的情况");
            BSTreeNode p = parent(k);
            if (p.left == k) {
                if (k.left != null) {
                    p.left = k.left;
                } else {
                    p.left = k.right;
                }
            } else if (p.right == k) {
                if (k.left != null) {
                    p.right = k.left;
                } else {
                    p.right = k.right;
                }
            }

        }
    }

    // 查找节点的前驱节点
    public BSTreeNode predecessor(BSTreeNode k) {
        if (k.left != null) {
            return searchMaxNode(k.left);// 左子树的最大值
        }
        BSTreeNode y = parent(k);
        //System.out.println("K的父节点(k的data为54):" + y.data);
        while (y != null && k == y.left) {// 向上找到最近的一个节点,其父亲节点的右子树包涵了当前节点或者其父亲节点为空
            k = y;
            y = parent(y);
        }
        return y;
    }

    // 查找节点的后继节点
    public BSTreeNode successor(BSTreeNode k) {
        if (k.right != null) {
            return searchMinNode(k.right);// 右子树的最小值
        }

        //为了避免54,87,43的情况
        BSTreeNode y = parent(k);
        //System.out.println("K的父节点(k的data为54):" + y.data);        
        if (y == null)
            return null;
        while (y != null) {
            if (y.left == k) {
                return y; //为左子树情况,后继为父节点
            } else {
                k = y; //否则递归
                y = parent(y);
            }
        }
        return y;
    }

    // 求出父亲节点,在定义节点类BSTreeNode的时候,没有申明父亲节点,所以这里专门用parent用来输出父亲节点(主要是不想修改代码了,就在这里加一个parent函数吧)
    public BSTreeNode parent(BSTreeNode k) {
        BSTreeNode p = rootNode;
        BSTreeNode tmp = null;
        while (p != null && p.data != k.data) {// 最后的p为p.data等于k.data的节点,tmp为p的父亲节点
            if (p.data > k.data) {
                tmp = p;// 临时存放父亲节点
                p = p.left;
            } else {
                tmp = p;// 临时存放父亲节点
                p = p.right;
            }
        }
        return tmp;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] A = { 23, 12, 12, 43, 2, 87, 54 };
        BSTreeNode searchNode1 = null;// 递归查找到的结果
        BSTreeNode searchNode2 = null;// 非递归查找到的结果
        BSTreeNode searchMinNode = null;// 最小节点
        BSTreeNode searchMaxNode = null;// 最大节点
        BSTreeNode k = null, l = null, p = null, q = null, m = null, n = null;// 申明6个节点k,l,p,q,m,n

        System.out.print("打印出数组A中的元素");
        for (int i = 0; i < A.length; i++)
            System.out.print(A[i] + ",");

        BSTree bs = new BSTree();
        bs.createBSTree(A);// 创建二叉查找树

        System.out.println();
        System.out.print("中序遍历构造的二叉查找树:");
        bs.inOrderBSTree(bs.rootNode);// 中序遍历二叉查找树

        k = new BSTreeNode(23, null, null);// 初始化一节点k,其data为null,左右孩子为null
        l = new BSTreeNode(17, null, null);// 初始化一节点l,其data为null,左右孩子为null
        q = new BSTreeNode(12, null, null);// 初始化一节点q,其data为null,左右孩子为null
        m = bs.searchBSTree2(bs.rootNode, k);// 从二叉查找树里面查找一个节点,其m.data为k.data(这个m节点在后面用来测试程序)
        searchNode1 = bs.searchBSTree1(bs.rootNode, k);// 查询二叉查找树----递归算法
        searchNode2 = bs.searchBSTree2(bs.rootNode, k);// 查询二叉查找树----递归算法

        System.out.println("");
        System.out.println("递归算法--查找节点域:" + searchNode1.data + "左孩子:"
                + searchNode1.left.data + "   右孩子:" + searchNode1.right.data);// 这里的左孩子或者右孩子节点可能打印为空,会出现null异常
        //System.out.println("非递归算法--查找节点域:" + searchNode2.data + "左孩子:"
                //+ searchNode2.left.data + "   右孩子:" + searchNode2.right.data);// 这里的左孩子或者右孩子节点可能打印为空,会出现null异常

        searchMinNode = bs.searchMinNode(bs.rootNode);// 找到最小节点
        searchMaxNode = bs.searchMaxNode(bs.rootNode);// 找到最大节点
        System.out.println("最小节点:" + searchMinNode.data);
        System.out.println("最大节点:" + searchMaxNode.data);

        bs.insert(l);// 把l节点插入到二叉查找树中
        System.out.println("插入l节点(l的data为17)之后的二叉查找树的中序遍历结果:");
        bs.inOrderBSTree(bs.rootNode);// 中序遍历二叉查找树

        p = bs.parent(bs.searchBSTree2(bs.rootNode, q));// 取q节点的父亲节点
        System.out.println("\nq的父亲节点(q的data为12):" + p.data + "   左孩子:"
                + p.left.data + "   右孩子:" + p.right.data);// 这里的左孩子或者右孩子节点可能打印为空,会出现null异常

        //bs.delete(l); //删除17
        //System.out.print("删除l节点(l的data为17)之后的二叉查找树的中序遍历结果:");
        //bs.inOrderBSTree(bs.rootNode);// 中序遍历二叉查找树
        
        bs.insert(new BSTreeNode(15, null, null));// 把l节点插入到二叉查找树中
        System.out.print("\n插入节点15之后的二叉查找树的中序遍历结果:");
        bs.inOrderBSTree(bs.rootNode);
        bs.delete(bs.searchBSTree2(bs.rootNode, q)); //删除12
        System.out.print("\n删除节点12之后的二叉查找树的中序遍历结果:");
        bs.inOrderBSTree(bs.rootNode);
        m = bs.searchBSTree2(bs.rootNode, k);
        System.out.println("\nm节点(m的data为23):" + m.data + "   左孩子:"
                + m.left.data + "   右孩子:" + m.right.data);

        BSTreeNode node = bs.searchBSTree1(bs.rootNode, new BSTreeNode(2, null,
                null));
        System.out.println("\ndata:" + node.data);
        n = bs.predecessor(node);
        if (n == null)
            System.out.println("K的前驱节点为:null");
        else
            System.out.println("K的前驱节点(k的data为" + node.data + "):" + n.data);
        n = bs.successor(node);
        if (n == null)
            System.out.println("K的后继节点为:null");
        else
            System.out.println("K的前驱节点(k的data为" + node.data + "):" + n.data);

    }

}

双向链表(doubly linked list)

View Code
class Node<T> {
    T value;
    Node<T> prev = null;
    Node<T> next = null;

    public boolean equals(Node<T> node) {
        if (value.equals(node.value)) {
            return true;
        }
        return false;
    }

    public int hashCode() {
        return value.hashCode();
    }

    public String toString() {
        if (value == null)
            return "-1";
        return value.toString();
    }
}

class DoubleLinkedList<T> {
    private Node<T> head; // 头节点
    private Node<T> tail;
    private int len; // 链表大小  

    //初始化LinkedList
    public DoubleLinkedList() {
        /*head = new Node<T>();
        tail = new Node<T>();

        head.next = tail;
        head.prev = null;
        tail.next = null;
        tail.prev = head;
        len = 0;*/
    }

    public void init() {
        head = new Node<T>();
        tail = new Node<T>();

        head.next = tail;
        head.prev = null;
        tail.next = null;
        tail.prev = head;
        len = 0;
    }

    public void destroyList() {

    }

    public void clearList() {
        init();
    }

    // 判断链表是否为空
    public boolean isEmpty() {
        if (tail == head.next || head == tail.prev) {
            return true;
        }
        return false;
    }

    // 链表的遍历(从head顺序遍历)
    public void traversalFromHead() {
        if (isEmpty()) {
            System.out.println("The Doubly Linked List is empty");
        } else {
            /*Node<T> node = head.next;
            while (null != node.next) {
                System.out.print(node + "-->");               
                node = node.next;
            }*/
            Node<T> node = head;
            len = 0;
            while (tail != node.next) {
                System.out.print(node.next + "-->");
                len++;
                node = node.next;
            }
            System.out.println();
        }
    }

    // 链表的遍历(从tail倒序遍历)
    public void traversalFromTail() {
        if (isEmpty()) {
            System.out.println("The Doubly Linked List is empty");
        } else {
            Node<T> node = tail.prev;
            while (null != node.prev) {
                System.out.print(node + "-->");
                node = node.prev;
            }
            System.out.println();
        }
    }

    public int getLength() {
        return len;
    }

    // 添加节点到链表的头部
    public void addToHead(Node<T> node) {
        /*if (tail == head.next) {
            head.next = node;
            tail.prev = node;
        } else {
            node.next = head.next;
            node.prev = head;
            head.next.prev = node;
            head.next = node;
        }*/
        // 修改node节点的前驱和后继
        node.next = head.next;
        node.prev = head; 
        // 修改node前驱节点的后继及后继节点的前驱
        head.next.prev = node;
        head.next = node;
    }

    // 添加节点到链表的尾部
    public void addToTail(Node<T> node) {
        /*if (tail.prev == head) {
            tail.prev = node;
            head.next = node;
        } else {
            node.prev = tail.prev;
            node.next = tail;
            tail.prev.next = node;
            tail.prev = node;
        }*/
        // 修改node节点的前驱和后继
        node.prev = tail.prev;
        node.next = tail;
        // 修改node前驱节点的后继及后继节点的前驱
        tail.prev.next = node;
        tail.prev = node;
    }

    // 添加某个值到指定的数值的节点前面
    public void insertBefore(Node<T> node, T key) {
        if (null == head.next || null == tail.prev) {
            System.out.println("The Doubly Linked List is empty");
        } else {
            Node<T> theNode = head.next;
            while (null != theNode.next) {
                if (theNode.next.value.equals(key)) {
                    node.next = theNode.next;
                    theNode.next.prev = node;
                    theNode.next = node;
                    node.prev = theNode;
                    break;
                }
                theNode = theNode.next;
            }
        }
    }

    // 添加某个值到指定的数值的节点后面
    public void insertAfter(Node<T> node, T key) {
        if (null == head.next || null == tail.prev) {
            System.out.println("The Doubly Linked List is empty");
        } else {
            Node<T> theNode = head;
            while (tail != theNode.next) {
                if (theNode.next.value.equals(key)) {
                    node.next = theNode.next.next;
                    theNode.next.next.prev = node;
                    theNode.next.next = node;
                    node.prev = theNode.next;
                    break;
                }
                theNode = theNode.next;
            }
        }
    }

    //删除第一个元素
    public void deleteFirst() {
        if (isEmpty()) {
            return;
        } else {
            head.next = head.next.next;//修改后继
            head.next.next.prev = head;//修改前驱
        }
    }

    //删除最后一个元素
    public void deleteLast() {
        if (!isEmpty()) {
            //顺序不能错
            tail.prev.prev.next = tail;//修改后继
            tail.prev = tail.prev.prev;//修改前驱            
        }
    }

    //判断指定的节点是否存在
    public boolean existsNode(Node<T> node) {
        boolean result = false;
        Node<T> tmp = head;
        while (tail != tmp.next) {
            if (!node.value.equals(tmp.next.value)) {
                result = false;
            } else {
                result = true;
                return result;
            }
            tmp = tmp.next;
        }
        return result;
    }

    //搜索指定位置的节点
    public Node<T> searchNode(int pos) {
        if (isEmpty()) {
            System.out.println("The Doubly Linked List is empty");
        } else {
            Node<T> node = head;
            int count = 0;
            if (pos >= len) {
                return null;
            } else {
                while (tail != node.next) {
                    if (count == pos) {
                        return node.next;
                    }
                    count++;
                    node = node.next;
                }
                System.out.println();
            }
        }
        return null;
    }

    //删除指定的node
    public void deleteNode(Node<T> node) {
        Node<T> tmp = head;
        if (existsNode(node)) {
            System.out.println("删除节点的值为:" + node.value);
            while (tail != tmp.next) {
                if (node.value.equals(tmp.next.value)) {
                    System.out.println("删除节点的前驱节点的值为:" + tmp.value);
                    tmp.next = tmp.next.next;//修改后继
                    tmp.next.next.prev = tmp;//修改前驱
                }
                tmp = tmp.next;
            }
        }
    }

    //删除指定位置的node
    public void deleteNode(int pos) {
         Node<T> node = searchNode(pos);
         System.out.println("位置从0开始,pos="+pos+"位置对应的节点值为:"+node.value);
         deleteNode(node);
    }
    
    //获取双向链表中第一个元素:不包括头指针
    public Node<T> getFirstNode()
    {
        return searchNode(0);
    }
    
    //获取双向链表最后一个元素:不包括尾指针
    public Node<T> getLastNode()
    {
        return searchNode(len-1);
    }

}

public class DoubleLinkedListTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        DoubleLinkedList<Integer> doublyLinkedList = new DoubleLinkedList<Integer>();
        /************************
         * 初始化操作
         * **********************/
        doublyLinkedList.init();
        System.out.println("########################################");
        System.out.println("新建双向链表:***");
        doublyLinkedList.traversalFromHead();
        for (int i = 0; i < 2; i++) {
            Node<Integer> node = new Node<Integer>();
            node.value = i;
            doublyLinkedList.addToHead(node);
        }
        System.out.println("########################################");
        System.out.println("初始化双向链表:***");
        doublyLinkedList.traversalFromHead();

        for (int i = 10; i < 16; i++) {
            Node<Integer> node = new Node<Integer>();
            node.value = i;
            doublyLinkedList.addToHead(node);
        }

        /************************
         * 插入操作
         * **********************/
        Node<Integer> node = new Node<Integer>();
        node.value = 88;
        doublyLinkedList.insertAfter(node, 11);

        node = new Node<Integer>();
        node.value = 24;
        doublyLinkedList.insertBefore(node, 11);

        node = new Node<Integer>();
        node.value = 100;
        doublyLinkedList.addToTail(node);
        System.out.println("########################################");
        System.out.println("双向链表插入操作:***");
        doublyLinkedList.traversalFromHead();
        System.out.println("双向链表长度为:" + doublyLinkedList.getLength());

        /************************
         * 删除操作
         * **********************/
        //删除当前双向链表中第一个节点
        doublyLinkedList.deleteFirst();
        //删除当前双向链表中最后节点
        doublyLinkedList.deleteLast();
        //删除当前双向链表中存在的节点
        node = new Node<Integer>();
        node.value = 11;
        doublyLinkedList.deleteNode(node);
        //删除不存在的节点
        node = new Node<Integer>();
        node.value = 1000;
        doublyLinkedList.deleteNode(node);
        System.out.println("########################################");
        System.out.println("双向链表删除操作:***");
        doublyLinkedList.traversalFromHead();
        System.out.println("双向链表长度为:" + doublyLinkedList.getLength());
        //删除指定位置的节点
        doublyLinkedList.deleteNode(1);
        System.out.println("双向链表删除操作:***");
        doublyLinkedList.traversalFromHead();
        System.out.println("双向链表长度为:" + doublyLinkedList.getLength());

        
        
        /************************
         * 清空列表操作
         * **********************/
        doublyLinkedList.clearList();
        System.out.println("########################################");
        System.out.println("双向链表清空操作:***");
        doublyLinkedList.traversalFromHead();
    }
}