代码地址: 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();
}
}

用基础Array数组实现动态数组、链表、栈和队列的更多相关文章

  1. JS 索引数组、关联数组和静态数组、动态数组

    JS 索引数组.关联数组和静态数组.动态数组 数组分类: 1.从数组的下标分为索引数组.关联数组 var ary1 = [1,3,5,8]; //按索引去取数组元素,从0开始(当然某些语言实现从1开始 ...

  2. "《算法导论》之‘队列’":队列的三种实现(静态数组、动态数组及指针)

    本文有关栈的介绍部分参考自网站数据结构. 1. 队列  1.1 队列的定义 队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表. (1)允许删除的一端称为队头(Front) ...

  3. solidity定长数组和动态数组

    固定长度的数组 固定长度数组声明 直接在定义数组的时候声明固定长度数组的值: uint[5] fixedArr = [1,2,3,4,5]; 可通过数组的length属性来获得数组的长度,进而进行遍历 ...

  4. C语言- 基础数据结构和算法 - 动态数组

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  5. array of TVarRec 动态数组使用

    FDQuery.AppendRecord()里是一个array of TVarRec.我们一般都是直接用[Var1,Var2,...].这样手工输入,但如果增加的元素我们预先不知道,就要声明一个arr ...

  6. C语言柔性数组和动态数组

    [前言]经常看到C语言里的两个数组,总结一下. 一.柔性数组 参考:https://www.cnblogs.com/veis/p/7073076.html #include<stdio.h> ...

  7. C语言数组:C语言数组定义、二维数组、动态数组、字符串数组

    1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...

  8. C/C++静态数组与动态数组的区别

    简介 以下三行代码有什么区别? int a[10]; int *a = (int*)malloc(sizeof(int)*10); int *a = new int[10]; 第一行代码定义a为包含1 ...

  9. "《算法导论》之‘栈’":栈的三种实现(静态数组、动态数组及指针)

    本文有关栈的介绍部分参考自网站数据结构. 1. 栈  1.1 栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底( ...

  10. Java程序猿学习C++之数组和动态数组

    数组: #include <iostream> using namespace std; //模板函数 template <class T> void dump(T val) ...

随机推荐

  1. 火山引擎VeDI:如何高效使用A/B实验,优化APP推荐系统

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在移动互联网飞速发展的时代,用户规模和网络信息量呈现出爆炸式增长,信息过载加大了用户选择的难度,这样的背景下,推荐 ...

  2. 升级版header吸顶后滑动变色(二)

    <van-nav-bar fixed id="opacityHeader"      //拉伸状态显示的header         title="赛事" ...

  3. WEB服务与NGINX(11)-NGINX状态页

    nginx状态页 nginx的状态页功能用于输出nginx的基本状态信息,基于ngx_http_stub_status_module模块实现. 默认情况下不生成此模块,应使用--with-http_s ...

  4. anaconda安装cv2库

    在安装cv2库之前,需要进行以下准备工作: 安装Anaconda 如果还没有安装Anaconda,可以在官网上下载对应操作系统的Anaconda安装包,然后按照提示进行安装.安装完成后,可以在终端中输 ...

  5. uni-app移动端开发中ios/安卓--坑和经验总结

    1. ios new时间对象,需要用逗号隔开传日期的方式, 不支持 new Date('2019-03-01 08:00:00') 格式: 支持以下两种方式: 2. ios个别版本对fixed的属性的 ...

  6. 稳定、省钱的 ClickHouse 读写分离方案:基于 JuiceFS 的主从架构实践

    Jerry 是一家位于北美的科技公司,利用人工智能和机器学习技术,简化汽车保险和贷款的比价和购买流程.在美国,Jerry 的应用在其所属领域排名第一. 随着数据规模的增长,Jerry 在使用 AWS ...

  7. 促双碳|AIRIOT智慧能源管理解决方案

      随着"双碳"政策和落地的推进,各行业企业围绕实现碳达峰和碳中和为目标,逐步开展智能化能源管理工作,通过能源数据统计.分析.核算.监测.能耗设备管理.碳资产管理等多种手段,对能源 ...

  8. 安装anaconda3卡在Unpacking payload ...

    ananconda3在centos7虚拟机上,直接进行ananconda3安装但是始终卡在Unpacking payload ..., 虚拟机的核心数调到2或者2以上即可解决

  9. 彻底搞懂JavaScript原型和原型链

    基于原型编程 在面向对象的编程语言中,类和对象的关系是铸模和铸件的关系,对象总是从类创建而来,比如Java中,必须先创建类再基于类实例化对象. 而在基于原型编程的思想中,类并不是必须的,对象都是通过克 ...

  10. wpf 斗地主 单机版 没有机器人出牌算法

    斗地主的游戏流程实现了,剩余的音效和机器人的出牌算法,抓地主算法就用最简单的实现. 主要实现了各种牌组的组合,牌组的大小比较,总共有16种牌组 基础牌组 单张.炸弹.炸弹型飞机带对子.炸弹型飞机什么都 ...