java数据结构——有序链表

  • 在有序链表中,数据时按照关键值排序的,有序链表的删除常常是只局限于删除在链表头部的最大(或最小)链结点。
  • 一般,在大多数需要使用有序数组的场合也可以使用有序链表,有序链表优于有序数组的地方是插入的速度(因为元素不需要移动),另外链表可以扩展到全部有效的使用内存,而数组只能局限一个固定的大小,但是,有序链表的实现确实比数组难一些。

   public class LinkOrder {

    static class Node {

        Integer data;
        Node next;

        public Node(Integer data) {
            this.data = data;
        }

    }


        private Node head;
        private int size;

        public LinkOrder() {
            this.head = null;
            this.size = 0;
        }

        // 判断是否为空
        private boolean isEmpty() {
            return head == null ? true : false;
        }

        // 获取链表大小
        private int getSize() {
            return size;
        }

        // 在链表中插入一个结点,保持链表有序性(头结点最小,尾结点最大)
        public void insert(int key) {
            Node newLink = new Node(key);
            Node previous = null;
            Node current = head;
            while (current != null && key > current.data) { // 找下个节点
                previous = current;
                current = current.next;
            }
            // 比当前节点值小,刚好插入当前节点前面
            if (previous == null) {// 链表是空的
                head = newLink;
            } else {
                previous.next = newLink;
            }
            newLink.next = current;
            size++;
        }

        // 返回头结点
        private Integer headNode() {
            if (head == null) {
                return null;
            }
            Integer value = head.data;
            return value;
        }

        // 删除头结点,并删除
        private Integer deleteHnode() {
            if (head == null) {
                return null;
            }
            Integer value = head.data;
            if (head.next == null) {
                head = null;
            } else {
                head = head.next;
            }
            size--;
            return value;
        }

        // 删除指定结点
        private void deleteNode(Node node) {
            if (head == null) {
                System.out.println("链表为空");
                return;
            }

            Node current = head;
            Node pre = null;
            while (current.data != node.data) {
                if (current.next == null) {
                    System.out.println("没有找到该结点");
                    return;
                }
                pre = current;
                current = current.next;
            }
            if (current == head) {
                deleteHnode();
            } else {
                pre.next = current.next;
                size--;
            }
        }

        // 遍历有序链表
        private void sysNode() {
            if (head == null) {
                System.out.println("该链表为空");
            }
            Node current = head;
            while (current != null) {
                System.out.print(current.data + "-->");
                current = current.next;
            }
            System.out.println();
        }

        public static void main(String[] args) {
            LinkOrder order = new LinkOrder();
            int i;
            Node node;
            for (i = 0; i < 5; i++) {
                order.insert(new Random().nextInt(100));
            }
            System.out.println("有序链表大小:" + order.getSize());
            order.sysNode();
            System.out.println("有序链表头结点:" + order.deleteHnode());
            order.sysNode();
            node = new Node(new Random().nextInt(100));
            System.out.println("删除指定结点:" + node.data);
            order.deleteNode(node);
            order.sysNode();

        }

    }

输出
java数据结构——有序链表_第1张图片

效率

  • 有序链表插入和删除某一项最多需要O(N)次比较(平均N/2),因为必须沿着链表一步一步找到正确的位置,然而,可以在O(1)的时间内找到或删除最小的值,因为它是表头,如果一个应用频繁的存取最小项,且不需要快速的插入,那么有序链表是最有效的一个方案选择。

总结

  • 有序链表中,链结点按照关键值的升序(有时降序)排列
  • 有序链表中插入需要O(N)的时间,因为必须找到正确的插入点,最小值连接点的删除需要O(1)的时间

你可能感兴趣的:(数据结构以及算法)