实现线性表:
- 定义一个MyList接口,继承Collection,关系如下图:
- 本次使用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;
}
}
- 实现线性表、队列及优先队列的方法有很多种,上述的是比较容易想到的,可能存在很多的错误,希望大家留言指正,谢谢。