代码地址: 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. WPF 触摸底层 PenImc 是如何工作的

    在 WPF 里面有其他软件完全比不上的超快速的触摸,这个触摸是通过 PenImc 获取的.现在 WPF 开源了,本文就带大家来阅读触摸底层的代码,阅读本文需要一点 C# 和 C++ 基础 现在 WPF ...

  2. WPF 动画实战 点击时显示圆圈淡出效果

    本文告诉大家一个有趣的动画,在鼠标点击的时候,在点击所在的点显示一个圆圈,然后这个圆圈做动画变大,但是颜色变淡的效果.本文的控件可以让大家将对应的容器放在自己应用里面就能实现这个效果 这个效果特别简单 ...

  3. RT-Thread线程同步与线程通信

    一.线程同步 线程同步的使用场景 例如一项工作中的两个线程:一个线程从传感器中接收数据并且将数据写到共享内存中,同时另一个线程周期性的从共享内存中读取数据并发送去显示,下图描述了两个线程间的数据传递: ...

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

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

  5. Spring 是如何造出一个 Bean 的

    前言 使用 Java 作为第一开发语言的朋友们,相信大家或多或少的都使用过 Spring 这个开发框架,可以说 Spring 框架真是我们 Java 程序员的春天,在 Spring 中 Bean 是其 ...

  6. arduino uno+LCD12864(ST7735S)+蓝牙模块实现贪吃蛇

    1.前言: 1.1本实验实现的贪吃蛇能穿越边界,结束游戏的唯一条件是贪吃蛇到达指定长度 1.2本实验所用LCD可能不是LCD12864,LCD12864所用库为u8glib,笔者在词库中并没有找到型号 ...

  7. 【OpenVINO™】使用OpenVINO™ C# API 部署 YOLO-World实现实时开放词汇对象检测

    YOLO-World是一个融合了实时目标检测与增强现实(AR)技术的创新平台,旨在将现实世界与数字世界无缝对接.该平台以YOLO(You Only Look Once)算法为核心,实现了对视频中物体的 ...

  8. 模型评测-书生浦语大模型实战营学习笔记7&大语言模型12

    大语言模型学习-12.模型评测 书生浦语大模型实战营学习笔记7 视频教程特别像广告,所以这篇博客参考了很多其他内容给大家参考,主要是下面几个页面: https://zhuanlan.zhihu.com ...

  9. LogAgen的工作流程

    LogAgen的工作流程: 一.读日志 --tailf 第三方库 新建tail_test/main.go package main import ( "fmt" "git ...

  10. WEB服务与NGINX(22)- nginx的七层负载均衡功能

    目录 1. NGINX实现负载均衡功能 1.1 nginx负载均衡概述 1.2 nginx实现http的负载均衡 1.2.1 nginx基于http负载均衡场景配置 1.2.1.1 负载均衡相关参数 ...