使用Java实现数据结构

前端开发者说 2020-08-13 ⋅ 16 阅读

概述

数据结构是计算机科学中非常重要的一部分,用于组织和管理数据的方式。在软件开发过程中,选择合适的数据结构可以提高算法的效率,从而提高程序的性能。

Java是一种面向对象的编程语言,提供了丰富的数据结构和算法库。本文将介绍一些常用的数据结构,并使用Java实现它们。

数组

数组是最简单的数据结构之一,它由相同类型的元素组成,并按照顺序进行排列。在Java中,数组的长度是固定的,一旦创建后无法改变。以下是一个使用Java实现的简单数组示例:

public class Array {
    private int[] data;
    private int size;

    public Array(int capacity) {
        data = new int[capacity];
        size = 0;
    }

    public int getSize() {
        return size;
    }

    public int getCapacity() {
        return data.length;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void add(int index, int value) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Invalid index");
        }

        if (size == data.length) {
            resize(2 * data.length);
        }

        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }

        data[index] = value;
        size++;
    }

    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Invalid index");
        }

        for (int i = index; i < size - 1; i++) {
            data[i] = data[i + 1];
        }

        size--;

        if (size <= data.length / 4 && data.length / 2 != 0) {
            resize(data.length / 2);
        }
    }

    public int get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Invalid index");
        }

        return data[index];
    }

    public void set(int index, int value) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Invalid index");
        }

        data[index] = value;
    }

    private void resize(int newCapacity) {
        int[] newData = new int[newCapacity];
        for (int i = 0; i < size; i++) {
            newData[i] = data[i];
        }
        data = newData;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Array: [");
        for (int i = 0; i < size; i++) {
            builder.append(data[i]);
            if (i != size - 1) {
                builder.append(", ");
            }
        }
        builder.append("]");
        return builder.toString();
    }
}

该数组实现包含一些常见的操作,如获取大小、判断是否为空、增加和删除元素、获取元素值等。在插入和删除元素时,如果数组已满或过于空闲,则会自动调整容量。

链表

链表是一种非连续存储的数据结构,它由节点组成,并使用指针将它们连接起来。在Java中,链表可以是单向、双向或循环的。以下是一个使用Java实现的单向链表示例:

public class LinkedList<T> {
    private class Node {
        public T value;
        public Node next;

        public Node(T value, Node next) {
            this.value = value;
            this.next = next;
        }

        public Node(T value) {
            this(value, null);
        }

        public Node() {
            this(null, null);
        }
    }

    private Node head;
    private int size;

    public LinkedList() {
        head = null;
        size = 0;
    }

    public int getSize() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void addFirst(T value) {
        head = new Node(value, head);
        size++;
    }

    public void addLast(T value) {
        Node node = new Node(value);

        if (isEmpty()) {
            head = node;
        } else {
            Node current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = node;
        }

        size++;
    }

    public void add(int index, T value) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Invalid index");
        }

        if (index == 0) {
            addFirst(value);
        } else if (index == size) {
            addLast(value);
        } else {
            Node prev = head;
            for (int i = 0; i < index - 1; i++) {
                prev = prev.next;
            }

            Node node = new Node(value);
            node.next = prev.next;
            prev.next = node;
            size++;
        }
    }

    public T removeFirst() {
        if (isEmpty()) {
            throw new NoSuchElementException("List is empty");
        }

        T value = head.value;
        head = head.next;
        size--;
        return value;
    }

    public T removeLast() {
        if (isEmpty()) {
            throw new NoSuchElementException("List is empty");
        }

        if (size == 1) {
            return removeFirst();
        } else {
            Node prev = head;
            while (prev.next.next != null) {
                prev = prev.next;
            }

            T value = prev.next.value;
            prev.next = null;
            size--;
            return value;
        }
    }

    public T remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Invalid index");
        }

        if (index == 0) {
            return removeFirst();
        } else if (index == size - 1) {
            return removeLast();
        } else {
            Node prev = head;
            for (int i = 0; i < index - 1; i++) {
                prev = prev.next;
            }

            Node nodeToRemove = prev.next;
            prev.next = nodeToRemove.next;
            size--;
            return nodeToRemove.value;
        }
    }

    public T get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Invalid index");
        }

        Node current = head;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }

        return current.value;
    }

    public void set(int index, T value) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Invalid index");
        }

        Node current = head;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }

        current.value = value;
    }

    public boolean contains(T value) {
        Node current = head;
        while (current != null) {
            if (current.value.equals(value)) {
                return true;
            }
            current = current.next;
        }
        return false;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("LinkedList: [");
        Node current = head;
        while (current != null) {
            builder.append(current.value);
            if (current.next != null) {
                builder.append(" -> ");
            }
            current = current.next;
        }
        builder.append("]");
        return builder.toString();
    }
}

该链表实现包含了一些常用的操作,如获取大小、判断是否为空、在头部和尾部插入元素、在指定位置插入元素、删除头部和尾部元素、删除指定位置的元素、获取指定位置的元素、设置指定位置的元素、判断是否包含指定元素等。

栈是一种先进后出(Last-In-First-Out,LIFO)的数据结构,类似于一叠盘子。在Java中,可以使用数组或链表实现栈。以下是一个使用Java实现的基于链表的栈示例:

public class LinkedListStack<T> {
    private class Node {
        public T value;
        public Node next;

        public Node(T value, Node next) {
            this.value = value;
            this.next = next;
        }

        public Node(T value) {
            this(value, null);
        }

        public Node() {
            this(null, null);
        }
    }

    private Node top;
    private int size;

    public LinkedListStack() {
        top = null;
        size = 0;
    }

    public int getSize() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void push(T value) {
        Node node = new Node(value, top);
        top = node;
        size++;
    }

    public T pop() {
        if (isEmpty()) {
            throw new NoSuchElementException("Stack is empty");
        }

        T value = top.value;
        top = top.next;
        size--;
        return value;
    }

    public T peek() {
        if (isEmpty()) {
            throw new NoSuchElementException("Stack is empty");
        }

        return top.value;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("LinkedListStack: [");
        Node current = top;
        while (current != null) {
            builder.append(current.value);
            if (current.next != null) {
                builder.append(" -> ");
            }
            current = current.next;
        }
        builder.append("]");
        return builder.toString();
    }
}

该栈实现包含了一些常用的操作,如获取大小、判断是否为空、入栈、出栈、获取栈顶元素。

队列

队列是一种先进先出(First-In-First-Out,FIFO)的数据结构,类似于排队。在Java中,可以使用数组或链表实现队列。以下是一个使用Java实现的基于数组的队列示例:

public class ArrayQueue<T> {
    private T[] data;
    private int front;
    private int rear;
    private int size;

    @SuppressWarnings("unchecked")
    public ArrayQueue(int capacity) {
        data = (T[]) new Object[capacity + 1];
        front = 0;
        rear = 0;
        size = 0;
    }

    public int getSize() {
        return size;
    }

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

    public void enqueue(T value) {
        if ((rear + 1) % data.length == front) {
            resize(2 * getCapacity());
        }

        data[rear] = value;
        rear = (rear + 1) % data.length;
        size++;
    }

    public T dequeue() {
        if (isEmpty()) {
            throw new NoSuchElementException("Queue is empty");
        }

        T value = data[front];
        data[front] = null;
        front = (front + 1) % data.length;
        size--;

        if (size <= getCapacity() / 4 && getCapacity() / 2 != 0) {
            resize(getCapacity() / 2);
        }

        return value;
    }

    public T getFront() {
        if (isEmpty()) {
            throw new NoSuchElementException("Queue is empty");
        }

        return data[front];
    }

    private void resize(int newCapacity) {
        @SuppressWarnings("unchecked")
        T[] newData = (T[]) new Object[newCapacity + 1];
        for (int i = 0; i < size; i++) {
            newData[i] = data[(i + front) % data.length];
        }
        data = newData;
        front = 0;
        rear = size;
    }

    private int getCapacity() {
        return data.length - 1;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("ArrayQueue: [");
        for (int i = front; i != rear; i = (i + 1) % data.length) {
            builder.append(data[i]);
            if ((i + 1) % data.length != rear) {
                builder.append(", ");
            }
        }
        builder.append("]");
        return builder.toString();
    }
}

该队列实现包含了一些常用的操作,如获取大小、判断是否为空、入队、出队、获取队首元素。

总结

本文介绍了Java中一些常用的数据结构,包括数组、链表、栈和队列,并给出了相应的实现代码。这些数据结构可以用于解决各种实际问题,在实际开发中非常有用。希望读者通过学习这些示例代码,对数据结构有更深入的理解,并能够灵活运用它们解决实际问题。


全部评论: 0

    我有话说: