用基础Array数组实现动态数组、链表、栈和队列
代码地址: https://gitee.com/Tom-shushu/Algorithm-and-Data-Structure.git
一、ArrayList自定义封装
package com.zhouhong; /** * @ClassName: array * @Description: 二次封装自己的数组类 * @Author: zhouhong * @Create: 2021-03-29 15:47 **/ public class Array <E> { private E[] data; private int size; // 构造函数,传入数组的容量 capacity 构造Array public Array(int capacity){ data = (E[])new Object[capacity]; size = 0; } // 无参构造函数,默认数组的容量 capacity = 10 public Array(){ this(10); } // 获取数组实际长度 public int getSize(){ return size; } // 获取容量 public int getCapacity(){ return data.length; } // 返回数组是否为空 public boolean isEmpty(){ return size == 0; } // 数组最后添加 O(n) public void addLast(E e){ add(size, e); } // 向数组头部添加元素 O(1) public void addFirst(E e){ add(0, e); } // 获取某个位置上的元素 O(1) public E get(int index){ if (index < 0 || index > size){ throw new IllegalArgumentException("index必须大于等于0 ,并且小于等于数组长度size"); } return data[index]; } // 更新元素 O(1) void set(int index, E e){ if (index < 0 || index >= size){ throw new IllegalArgumentException("index必须大于等于0 ,并且小于等于数组长度size"); } data[index] = e; } // 向指定位置添加元素 O(n) public void add(int index, E e){ if (index < 0 || index > size){ throw new IllegalArgumentException("index必须大于等于0 ,并且小于等于数组长度size"); } // 数组已满:扩容 if (size == data.length){ // 扩容 2 倍 resize(data.length * 2); } for (int i = size - 1; i >= index ; i--) { data[i + 1] = data[i]; } data[index] = e; size ++; } // 查找数组中是否有元素e O(n) public boolean contains(E e){ for (int i = 0; i < size; i++) { if (data[i].equals(e)){ return true; } } return false; } // 查找某个元素对应的索引(重复元素只返回一个索引) O(n) public int find(E e){ for (int i = 0; i < size; i++) { if (data[i].equals(e)){ return i; } } return -1; } // 删除某个指定索引上的元素(直接覆盖、前移),返回删除的元素 O(n) public E remove(int index){ if (index < 0 || index >= size){ throw new IllegalArgumentException("index必须大于等于0 ,并且小于等于数组长度size"); } E result = data[index]; for (int i = index; i < size; i++) { data[i] = data[i + 1]; } size --; data[size] = null; // 当长度小于容量的 1/2 把容量自动缩小为原来长度的 1/2 // 懒加载,当为1/4时缩容 if (size == data.length >> 2 && data.length >> 1 != 0){ resize(data.length / 2); } return result; } // 删除第一个元素 O(n) public E removeFirst(){ return remove(0); } // 删除最后一个元素 O(1) public E removeLast(){ return remove(size - 1); } // 如果数组中有某个元素,就删除(相同元素,只删除一个) public void removeElenent(E e){ int index = find(e); if (index != -1){ remove(index); } } // 扩容 private void resize(int newCapacity){ E[] newData = (E[]) new Object[newCapacity]; for (int i = 0; i < size; i++) { newData[i] = data[i]; } data = newData; } @Override public String toString() { StringBuilder result = new StringBuilder(); result.append(java.lang.String.format("Array: size = %d, capacity = %d\n", size, data.length)); result.append('['); for (int i = 0; i < size; i++) { result.append(data[i]); if (i != size - 1){ result.append(", "); } } result.append(']'); return result.toString(); } }
二、用我们自定义的动态数组实现队列
package com.zhouhong; /** * @ClassName: array-queue * @Description: 基于数组的普通队列 * @Author: zhouhong * @Create: 2021-03-30 23:55 **/ public class ArrayQueue<E> implements QueueInterface<E> { private Array<E> array; public ArrayQueue(int capacity){ array = new Array<>(capacity); } public ArrayQueue(){ array = new Array<>(); } @Override public void enqueue(E e) { array.addLast(e); } @Override public E dequeue() { return array.removeFirst(); } @Override public E getFront() { return array.getFirst(); } @Override public int getSize() { return array.getSize(); } public int getCapacity() { return array.getCapacity(); } @Override public boolean isEmpty() { return array.isEmpty(); } @Override public String toString(){ StringBuilder res = new StringBuilder(); res.append("Queue:"); res.append("front ["); for (int i = 0; i < array.getSize(); i++) { res.append(array.get(i)); if (i != array.getSize() - 1){ res.append(", "); } } res.append("] tail"); return res.toString(); } }
三、使用动态数组实现栈
package com.zhouhong; /** * @ClassName: stack * @Description: 使用数组实现一个栈 * @Author: zhouhong * @Create: 2021-03-30 22:37 **/ public class ArrayStack<E> implements StackInterface<E>{ Array<E> array; public ArrayStack(int capacity){ array = new Array<>(capacity); } public ArrayStack(){ array = new Array<>(); } @Override public int getSize() { return array.getSize(); } @Override public boolean isEmpty() { return array.isEmpty(); } @Override public void push(E e) { array.addLast(e); } @Override public E pop() { return array.removeLast(); } @Override public E peek() { return array.getLast(); } public int getCapacity(){ return array.getCapacity(); } @Override public String toString(){ StringBuilder res = new StringBuilder(); res.append("Stack:"); res.append('['); for (int i = 0; i < array.getSize(); i++) { res.append(array.get(i)); if (i != array.getSize() - 1){ res.append(", "); } } res.append("] top"); return res.toString(); } }
四、链表常见操作实现
package com.zhouhong; /** * @ClassName: linkedlist * @Description: 链表 * @Author: zhouhong * @Create: 2021-03-31 15:25 **/ public class LinkedList<E> { private class Node{ public E e; public Node next; public Node(E e, Node next){ this.e = e; this.next = next; } public Node(E e){ this(e, null); } public Node(){ this(null, null); } @Override public String toString(){ return e.toString(); } } //使用head,会使得add方法在向首部添加元素时找不到当前元素对应的前一个元素 // private Node head; // 虚拟头结点 private Node dummyHead; private int size; public LinkedList(){ dummyHead = new Node(null, null); size = 0; } // 获取链表中的元素的个数 public int getSize(){ return size; } // 返回链表是否为空 public boolean isEmpty(){ return size == 0; } // 在链表index中间添加元素 public void add(E e, int index){ if (index < 0 || index > size){ throw new IllegalArgumentException("ADD failed, Illegal index."); } Node pre = dummyHead; // 遍历找到所要插入节点的前一个节点 for (int i = 0; i < index; i++) { pre = pre.next; } // Node node = new Node(e); // node.next = pre.next; // pre = node; pre.next = new Node(e, pre.next); size ++; } // 为链表头部添加元素 public void addFirst(E e){ // Node node = new Node(e); // node.next = head; // head = node; add(e,0); } // 想链表末尾添加元素 public void addLast(E e){ add(e, size); } // 获得链表的第index 个位置的元素 // 在链表中不是一个常用的操作,练习用 public E get(int index){ if (index < 0 || index >= size){ throw new IllegalArgumentException("ADD failed, Illegal index."); } Node cur = dummyHead.next; for (int i = 0; i < index; i++) { cur = cur.next; } return cur.e; } // 获得第一个元素 public E getFirst(){ return get(0); } // 获得最后一个元素 public E getLast(){ return get(size - 1); } // 修改链表的第 index 个位置的元素为e // 在链表中不是一个常用的操作,练习用 public void set(int index, E e){ if (index < 0 || index > size){ throw new IllegalArgumentException("Update failed, Illegal index."); } Node cur = dummyHead.next; // 遍历找到所要插入节点的前一个节点 for (int i = 0; i < index; i++) { cur = cur.next; } cur.e = e; } // 查找链表中是否存在元素e public boolean contains(E e){ Node cur = dummyHead.next; while (cur != null){ if (cur.e.equals(e)){ return true; } cur = cur.next; } return false; } // 从链表中删除index位置的元素,返回待删除元素 public E remove(int index){ if (index < 0 || index > size){ throw new IllegalArgumentException("remove failed, Illegal index."); } Node pre = dummyHead; // 遍历找到所要删除节点的前一个节点 for (int i = 0; i < index; i++) { pre = pre.next; } Node node = pre.next; pre.next = node.next; node.next = null; size --; return node.e; } // 从链表中删除第一个元素,返回删除元素 public E removeFirst(){ return remove(0); } // 从链表中删除最后一个元素,返回删除元素 public E removeLast(){ return remove(size - 1); } @Override public String toString(){ StringBuilder res = new StringBuilder(); Node cur = dummyHead.next; while (cur != null){ res.append(cur + "->"); cur = cur.next; } res.append("NULL"); return res.toString(); } }
本文来自博客园,作者:Tom-shushu,转载请注明原文链接:https://www.cnblogs.com/Tom-shushu/p/14611002.html