代码地址: 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. Linux服务器安装GaussDB 100及安装过程中常见问题解决

    ******************************** Gaussdb 100安装 ******************************** 1. 创建安装包目录 mkdir -p ...

  2. uni.request二次封装

    点击查看代码 const baseUrl = 'https://your-api-base-url.com'; function getAuthToken() { // 获取token的逻辑,可能会从 ...

  3. 2023年的Clion内建立多个子项目(保姆级教程)

    目录 下载插件C/C++ Single File Execution 项目操作 其他操作 下载插件C/C++ Single File Execution 项目操作 1.新建项目-->如图所示操作 ...

  4. Azure Service Principals ----- Azure 上最好保守的秘密的服务

    一,引言 Azure Service Principals 是 Azure Active Directory (AAD) 中的一种标识,代表应用程序,服务,自动化流程.Service Principa ...

  5. 树莓派 ubuntu server 22.x 连接无线网络

    前言 树莓派系统安装完成后,需要配置网络,由于家里没有多余的网线(网线多少有点乱),所以决定配置无线上网的方式,现在记录下来操作过程 具体操作 sudo nano /etc/netplan/xxxxx ...

  6. 卷爆短剧出海:五大关键,由AIGC重构

    短剧高温下,谈谈AIGC的助攻路线. 短剧,一个席卷全球的高温赛道. 以往只是踏着霸总题材,如今,内容循着精品化.IP化的自然发展风向,给内容.制作.平台等产业全链都带来新机,也让短剧消费走向文化深处 ...

  7. unity 新input system 鼠标点在ui上检测的两种方法

    哪种有用就用哪种.EventSystem.current.IsPointerOverGameObject()有可能不好使. using System.Collections.Generic; usin ...

  8. yapi-plugin-notifier 插件安装报react 16.9.0版本错误 解决

    使用yapi 1.9.2版本. 将配置的json文件替换掉. 参考这个issues解决方案:https://github.com/YMFE/yapi/issues/2109

  9. Dockerfile PHP镜像制作

    1 PHP镜像制作: 1.1 php-dockerfile FROM centos:7 LABEL maintainer www.chenleilei.net RUN yum install -y c ...

  10. windows下IPv4通信(C++、MFC)

    Cilect #include <stdio.h> #include <Ws2tcpip.h> #include <winsock2.h> #define HELL ...