实现线性表、队列及优先队列

实现线性表:

  • 定义一个MyList接口,继承Collection,关系如下图:
    上图展示了Collection、MyList、MyArrayList之间的继承关系
  • 本次使用MyArrayList来实现线性表。

MyList接口

import java.util.Collection;

public interface MyList<E> extends Collection<E> {

    public void add(int index, E e);

    public E get(int index);

    public int indexOf(Object e);

    public int lastIndexOf(E e);

    public E remove(int index);

    public E set(int index, E e);

    @Override
    public default boolean add(E e) {
        add(size(), e);
        return true;
    }

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

    @Override
    public default boolean remove(Object e) {
        if (indexOf(e) >= 0) {
            remove(indexOf(e));
            return true;
        }
        else
            return false;
    }

    @Override
    public default boolean containsAll(Collection<?> c) {
        return true;
    }

    @Override
    public default boolean addAll(Collection<? extends E> c) {
        return true;
    }

    @Override
    public default boolean removeAll(Collection<?> c) {
        return true;
    }

    @Override
    public default boolean retainAll(Collection<?> c) {
        return true;
    }

    @Override
    public default Object[] toArray() {
        return null;
    }

    @Override
    public default <T> T[] toArray(T[] array) {
        return null;
    }
}

  • 定义MyArrayList类实现MyList接口:

MyArrayList类

import com.javase.inte.MyList;
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;

import java.util.Iterator;

public class MyArrayList<E> implements MyList<E> {
    public static final int INITIAL_CAPACITY = 16;
    private E[] data = (E[])new Object[INITIAL_CAPACITY];
    private int size = 0;

    public MyArrayList() {

    }

    public MyArrayList(E[] objects) {
        for (int i = 0; i < objects.length; i++)
            add(objects[i]);
    }

    @Override
    public void add(int index, E e) {//将元素插入到指定下标处
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        ensureCapacity();

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

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

    private void ensureCapacity() {//检验数组是否已满
        if (size >= data.length) {
            E[] newData = (E[]) new Object[size * 2 + 1];
            System.arraycopy(data, 0, newData, 0, size);
            data = newData;
        }
    }

    @Override
    public void clear() {//创建一个新的下标为INITIAL_CAPACITY的size为空的数组
        data = (E[]) new Object[INITIAL_CAPACITY];
        size = 0;
    }

    @Override
    public E get(int index) {//检查index是否在范围内,如果在,返回data[index]
        checkIndex(index);
        return data[index];
    }

    private void checkIndex(int index) {//检查index是否在范围内,不在则返回异常
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
    }

    @Override
    public int indexOf(Object e) {//从头开始,逐一比较,存在则返回下标
        for (int i = 0; i < size; i++)
            if (e.equals(data[i])) return i;
        return -1;
    }

    @Override
    public int lastIndexOf(E e) {//从尾开始,逐一比较,存在则返回下标
        for (int i = size - 1; i >= 0; i--)
            if (e.equals(data[i])) return i;
        return -1;
    }

    @Override
    public E remove(int index) {//将指定下标之后的所有元素向左移动一个位置,数组size-1
        checkIndex(index);

        E e = data[index];

        for (int j = index; j < size - 1; j++)
            data[j] = data[j + 1];

        data[size - 1] = null;
        size--;

        return e;
    }

    @Override
    public E set(int index, E e) {//将e赋值给data[index],数组下标用e替换
        checkIndex(index);
        E old = data[index];
        data[index] = e;
        return old;
    }

    @Override
    public String toString() {//重写toString方法
        StringBuilder result = new StringBuilder("[");
        for (int i = 0; i < size; i++) {
            result.append(data[i]);
            if (i < size - 1) result.append(", ");
        }
        return result.toString() + "]";
    }

    @Override
    public int size() {//返回数组元素数目
        return size;
    }



    @Override
    public boolean contains(Object e) {//逐一比较,判断是否含有元素e
        for (int i = 0; i < size; i++)
            if (e.equals(data[i])) return true;
        return false;
    }

    public void trimToSize() {//创建一个新数组
        if (size != data.length) {
            E[] newData = (E[]) (new Object[size]);
            System.arraycopy(data, 0, newData, 0, size);
            data = newData;
        }
    }

    @Override
    public Iterator<E> iterator() {//返回一个迭代器实例
        return new ArrayLikeIterator();
    }

    private class ArrayLikeIterator implements Iterator<E> {

        private int current = 0;

        @Override
        public boolean hasNext() {
            return current < size;
        }

        @Override
        public E next() {
            return data[current++];
        }

        @Override
        public void remove() {
            if (current == 0)
                throw new IllegalStateException();
            MyArrayList.this.remove(--current);
        }
    }
}

  • 测试线性表实现:

测试类TestMyArrayList

import com.javase.inte.impl.MyArrayList;

public class TestMyArrayList {
    public static void main(String[] args) {
        MyList<String> list  = new MyArrayList<>();

        list.add("China");
        System.out.println("(1)" + list);

        list.add(0, "Canada");
        System.out.println("(2)" + list);

        list.add("America");
        System.out.println("(3)" + list);

        list.add("France");
        System.out.println("(4)" + list);

        list.add(2,"Germany");
        System.out.println("(5)" + list);

        list.add(5, "Norway");
        System.out.println("(6)" + list);

        list.remove("Canada");
        System.out.println("(7)" + list);

        list.remove(2);
        System.out.println("(8)" + list);

        list.remove(list.size() - 1);
        System.out.print("(9)" + list + "\n(10)");

        for (String s: list)
            System.out.print(s.toUpperCase() + " ");
    }
}

实现队列:

  • 有两种方法实现设计队列的类
    -使用继承:可以通过继承链表类LinkedList来定义队列类;
    -使用组合:将链表定义为数组中的数据域。

  • 上述两种方法均可,第二种可能会更好一点,本次使用第二种方法实现。

GenericQueue类

import java.util.LinkedList;

public class GenericQueue<E> {
    private LinkedList<E> list = new LinkedList<>();

    public void equeue(E e) {
        list.addLast(e);
    }

    public E dequeue() {
        return list.removeFirst();
    }

    public int getSize() {
        return list.size();
    }

    @Override
    public String toString() {
        return "Queue: " + list.toString();
    }
}

  • 创建测试方法:

测试类TestQueue

package com.javase.generic;

public class TestQueue {
    public static void main(String[] args) {
        GenericQueue<String> queue = new GenericQueue<>();

        queue.equeue("Tom");
        System.out.println("(1)" + queue);

        queue.equeue("Jerry");
        System.out.println("(2)" + queue);

        queue.equeue("kim");
        queue.equeue("cat");
        System.out.println("(3)" + queue);

        System.out.println("(4)" + queue.dequeue());
        System.out.println("(5)" + queue.dequeue());
        System.out.println("(6)" + queue);
    }
}

实现优先队列

  • 普通的队列是一种先进先出的数据结构,在优先队列中,元素被赋予优先级。
  • 使用堆实现优先队列,其中根节点是队列中具有最高优先级的对象。

MyPriorityQueue类

import com.javase.Heap.Heap;

public class MyPriorityQueue<E extends Comparable<E>> {
    private Heap<E> heap = new Heap<>();

    public void enqueue(E newObject) {
        heap.add(newObject);
    }

    public E dequeue() {
        return heap.remove();
    }

    public int getSize() {
        return heap.getSize();
    }
}

  • 创建测试方法

测试类TestPriorityQueue

package com.javase.generic;

public class TestPriorityQueue {
    public static void main(String[] args) {
        Patient patient1 = new Patient("john", 2);
        Patient patient2 = new Patient("jim", 1);
        Patient patient3 = new Patient("tim", 5);
        Patient patient4 = new Patient("cindy", 7);

        MyPriorityQueue<Patient> priorityQueue = new MyPriorityQueue<>();
        priorityQueue.enqueue(patient1);
        priorityQueue.enqueue(patient2);
        priorityQueue.enqueue(patient3);
        priorityQueue.enqueue(patient4);

        while (priorityQueue.getSize() > 0)
            System.out.println(priorityQueue.dequeue() + "  ");
    }
}

class Patient implements Comparable<Patient> {
    private String name;
    private int priority;

    public Patient(String name, int priority) {
        this.name = name;
        this.priority = priority;
    }

    @Override
    public String toString() {
        return name + "(priority:" + priority + ")";
    }

    @Override
    public int compareTo(Patient patient) {
        return this.priority - patient.priority;
    }
}

  • 实现线性表、队列及优先队列的方法有很多种,上述的是比较容易想到的,可能存在很多的错误,希望大家留言指正,谢谢。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值