java 数据结构--链式表

DEMO地址:https://github.com/zhaopingfu/MDataStruct

java中常用的链式表是LinkedList

  • 优点:增加,删除元素效率高
  • 缺点:查询,修改元素效率低

LinkedList中有一个Node内部类,该类中有两个属性,一个是next,一个是previous,相当于两个指针,有一个占位符root,当查找元素的时候就可以根据root,root.next就是整个链表的第一个元素,root.previous就是整个链表最后一个元素

这里的root元素是不看做链表里的元素的,只是个占位符

单向链表

package com.pf;

/**
 * @author zhaopf
 * @version 1.0
 * @QQ: 1308108803
 * @date 2017年11月14日
 * 单链表
 */
public class MSinglyLinkedList<T> {

    private Node<T> first;
    private Node<T> last;
    private int size;

    public boolean add(T data) {
        Node<T> node = new Node<>(null, data);
        if (first == null) {
            first = node;
            last = node;
        } else {
            last.next = node;
            last = node;
        }
        size++;
        return true;
    }

    public boolean add(int index, T data) {
        if (index >= 0 && index <= size) {
            if (index == size) {
                return add(data);
            } else if (index == 0) {
                Node<T> node = first;
                Node<T> newNode = new Node<>(node, data);
                newNode.next = node;
                first = newNode;
                size++;
                return true;
            } else {
                Node<T> node = elementData(index - 1);
                Node<T> newNode = new Node<>(node.next, data);
                node.next = newNode;
                size++;
                return true;
            }
        }
        throw new ArrayIndexOutOfBoundsException("index:" + index + ",size:" + size);
    }

    public T get(int index) {
        checkIndex(index);
        return elementData(index).data;
    }

    public T set(int index, T newData) {
        checkIndex(index);
        Node<T> node = elementData(index);
        T result = node.data;
        node.data = newData;
        return result;
    }

    public boolean remove(int index) {
        checkIndex(index);
        if (index == 0) {
            first = first.next;
            size--;
            if (first == null) {
                last = null;
            }
            return true;
        } else if (index == size - 1) {
            Node<T> node = elementData(index - 1);
            node.next = null;
            size--;
            last = node;
            if (last == null) {
                first = null;
            }
            return true;
        } else {
            Node<T> node = elementData(index - 1);
            node.next = node.next.next;
            size--;
            return true;
        }
    }

    public boolean remove(T data) {
        if (data == null) {
            Node<T> node = first;
            int i = 0;
            while (node != null) {
                if (node.data == null) {
                    return remove(i);
                }
                node = node.next;
                i++;
            }
        } else {
            Node<T> node = first;
            int i = 0;
            while (node != null) {
                if (data.equals(node.data)) {
                    return remove(i);
                }
                node = node.next;
                i++;
            }
        }
        return false;
    }

    Node<T> elementData(int index) {
        Node<T> temp = first;
        for (int i = 0; i < index; i++) {
            temp = temp.next;
        }
        return temp;
    }

    private void checkIndex(int index) {
        if (index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException("index:" + index + ",size:" + size);
        }
    }

    public int size() {
        return size;
    }

    private class Node<T> {
        private Node<T> next;
        private T data;

        public Node(Node<T> next, T data) {
            this.next = next;
            this.data = data;
        }
    }
}

双向循环链表

个人写了个类似的,实现了增删改查功能

package com.pf;

public class MLinkedList<T> {

    private Node<T> root;
    private int size;

    public MLinkedList() {
        root = new Node<T>(null, null, null);
    }

    public boolean add(T data) {
        addLast(data);
        return true;
    }

    public boolean add(int index, T data) {
        if (index >= 0 && index <= size) {
            if (index == size) {
                addLast(data);
            } else {
                Node<T> node = elementData(index);
                addBefore(node, data);
            }
            return true;
        }
        throw new ArrayIndexOutOfBoundsException("index is " + index + ", size is " + size);
    }

    public T get(int index) {
        return elementData(index).data;
    }

    public T set(int index, T newData) {
        checkIndex(index);
        Node<T> node = elementData(index);
        T result = node.data;
        node.data = newData;
        return result;
    }

    public boolean remove(int index) {
        checkIndex(index);
        return delete(index);
    }

    public boolean remove(T data) {
        if (data == null) {
            Node<T> temp = root.next;
            while (temp != root) {
                if (temp.data == null) {
                    temp.previous.next = temp.next;
                    temp.next.previous = temp.previous;
                    temp = null;
                    size--;
                    return true;
                }
                temp = temp.next;
            }
        } else {
            Node<T> temp = root.next;
            while (temp != root) {
                if (data.equals(temp.data)) {
                    temp.previous.next = temp.next;
                    temp.next.previous = temp.previous;
                    temp = null;
                    size--;
                    return true;
                }
                temp = temp.next;
            }
        }
        return false;
    }

    private boolean delete(int index) {
        Node<T> oldLast = elementData(index);
        oldLast.previous.next = oldLast.next;
        oldLast.next.previous = oldLast.previous;
        oldLast = null;
        size--;
        return true;
    }

    private void addBefore(Node<T> oldNode, T data) {
        Node<T> preNode = oldNode.previous;
        Node<T> newNode = new Node<T>(preNode, data, oldNode);
        preNode.next = newNode;
        oldNode.previous = newNode;
        size++;
    }

    private void addLast(T data) {
        Node<T> oldLast = root.previous;
        Node<T> newNode = new Node<T>(oldLast, data, root);
        if (oldLast == null) {
            root.next = newNode;
            root.previous = newNode;
            newNode.previous = root;
        } else {
            oldLast.next = newNode;
            root.previous = newNode;
        }
        size++;
    }

    Node<T> elementData(int index) {
        if (index < (size >> 2)) {
            Node<T> temp = root.next;
            for (int i = 0; i < index; i++) {
                temp = temp.next;
            }
            return temp;
        } else {
            Node<T> temp = root.previous;
            for (int i = size - 1; i > index; i--) {
                temp = temp.previous;
            }
            return temp;
        }
    }

    private void checkIndex(int index) {
        if (index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException("index is " + index + ", size is " + size);
        }
    }

    @SuppressWarnings("hiding")
    private class Node<T> {

        private Node<T> previous;
        private Node<T> next;
        private T data;

        public Node(Node<T> previous, T data, Node<T> next) {
            super();
            this.previous = previous;
            this.next = next;
            this.data = data;
        }
    }

    public int size() {
        return size;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值