本专栏为本人初学数据结构所记,如有错误希望各位博友帮忙指正,共同进步!🥰🥰🥰
目录
1. 顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成
数据的增删查改。下面将会由阿漓带着大家来自己实现一个顺序表
2. 自己实现一个MyArrayList
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.1 初始化顺序表
顺序表说白了就是一个在数组上进行操作的结构,首先,这里我们创建一个空间为5 的数组
public class MyArrayList {
public int[] elem;// 创建一个数组
public int usedSize;// 记录数组当中的有效长度
public static final int DEFAULT_CAPACITY = 5;// 定义一个常量
public MyArrayList(){
this.elem = new int[DEFAULT_CAPACITY];// 将数组的内存置为5
}
}
下面我会一个方法一个方法的去实现与讲解
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.2 打印顺序表方法
display()方法
只需一个for循环就可以搞定啦
// 打印顺序表 只需要打印到usedSize下标就可以了
public void display() {
for (int i = 0; i < this.usedSize; i++) {
// 打印elem数组中下标为i的元素
System.out.print(this.elem[i]+" ");
}
System.out.println();
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.3 新增元素,默认在数组最后新增
add(int data) 方法
大部分人的思路都是以下这种思路:
- 将数值放入到 i 下标
- usedSize 进行++
// 新增元素,默认在数组最后新增
public void add(int data) {
this.elem[useSize] = data;
this.usedSize++;
}
而在这里我们还需要去考虑一个问题,如果此时数组当中的元素添加满了该怎么办呢?
这个时候数组就应该需要扩容了,所以正确的思路应该是
- 判断数组是否已满
- 将数值放入到 i 下标
- usedSize ++
千万别忘记了 " 判满扩容 " 问题!!! \color{red}{千万别忘记了"判满扩容"问题!!!} 千万别忘记了"判满扩容"问题!!!
// 新增元素,默认在数组最后新增
public void add(int data) {
// 判断是否已满!
if (isFull()) {
// 满了就去以原数组两倍的长度去进行扩容
this.elem = Arrays.copyOf(elem,2*elem.length);
}
this.elem[usedSize] = data;
this.usedSize++;
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.3.1 判断数组是否已满
isFull() 方法
public boolean isFull() {
// 注意这里应该与实时的数组长度去判断,
// 而不可以去和DEFAULT_CAPACITY判断
return this.usedSize == this.elem.length-1;
}
这里也不能写return this.usedSize == this.elem.length;扩容需要到了倒数第二个元素开始放的时候就扩容!😋
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.4 在pos位置新增元素
add(int pos,int data)方法
思路:
- 首先判断 pos 位置的合法性
- 不合法应该抛出异常
- usedSize++
// 在pos位置新增元素
public void add(int pos,int data){
try {
checkAddPos(pos);
for (int i = usedSize-1; i >= pos; i--) {
elem[i+1] = elem[i];
}
elem[pos] = data;
usedSize++;
}catch (PosIndexNotLegalException e) {
e.printStackTrace();
}
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.4.1 判断add方法中pos是否合法
checkAddPos(int pos)方法
/**
* 检查add元素的时候,pos位置是否合法
* 设计为 private 是因为当前方法只是服务于当前类当中的 add 方法
* @param pos
*/
private void checkAddPos(int pos) {
if (pos < 0 || pos >= usedSize) {// 判断pos位置是否合法
throw new PosIndexNotLegalException("pos位置不合法!");
}
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.4.1.1 pos 位置异常
PosIndexNotLegalException异常
在这里我们自定义一个异常,继承于运行时异常
public class PosIndexNotLegalException extends RuntimeException {
public PosIndexNotLegalException() {
}
public PosIndexNotLegalException(String msg) {
super(msg);
}
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.5 判断是否包含某个元素
contains(int toFind)方法
// 判断是否包含某个元素
public boolean contains(int toFind) {
//在这里不用判断是否为空
//如果为空那么就会返回false
for (int i = 0; i < this.elem.length; i++) {
if (this.elem[i] == toFind) {
return true;
}
}
return false;
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.6 查找某个元素对应的位置
indexOf(int toFind)方法
// 查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (toFind == elem[i]) {
return i;
}
}
return -1;
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.7 查找某个元素对应的位置
indexOf(int toFind)方法
// 查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (toFind == elem[i]) {
return i;
}
}
return -1;
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.8 获取 pos 位置的元素
get(int pos)方法
// 获取 pos 位置的元素
public int get(int pos) {
checkGetPos(pos);
return this.elem[pos];
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.8.1 检查pos位置是否合法
checkGetPos(int pos)方法
/**
* 检查get元素的时候,pos位置是否合法
* 设计为 private 是因为当前方法只是服务于当前类当中的 add 方法
* @param pos
*/
private void checkGetPos(int pos) {
if (pos < 0 || pos >= usedSize) {// 判断pos位置是否合法
throw new PosIndexNotLegalException("pos位置不合法!");
}
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.9 给 pos 位置的元素设置为value
set(int pos, int value)
public void set(int pos, int value) {
checkGetPos(pos);
this.elem[pos] = value;
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.10 删除第一次出现的关键字key
remove(int key)方法
public void remove(int key) {
int index = indexOf(key);// 先找到key元素的下标
if (index == -1) {
System.out.println("没有你要删除的树数字!");
return;
}
for (int i = index; i < usedSize-1; i++) {
elem[i+1] = elem[i];// 拿后一个把前一个覆盖掉
}
usedSize--;
// 最后一个元素并没有删除,只是usedSize变小最后一个元素被盖掉了
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.11 获取顺序表长度
size()方法
public int size() {
return usedSize;// 直接返回有效长度即可
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2.12 清空顺序表
clear()方法
public void clear() {
//因为是简单类型所以以下代码可以不写
// for (int i = 0; i < elem.length; i++) {
// this.elem[i] = null;
// }
usedSize = 0;
}
− − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − − \color{green}{----------------------------------------------} −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
public class MyArrayList {
public int[] elem;
public int usedSize;
public static final int DEFAULT_CAPACITY = 5;
public MyArrayList(){
elem = new int[DEFAULT_CAPACITY];
}
public void display(){
for (int i = 0; i < usedSize; i++) {
System.out.print(elem[i]+" ");
}
System.out.println();
}
public void add(int data){
if (isFull()) {
elem = Arrays.copyOf(elem,2*elem.length);
}
elem[usedSize] = data;
usedSize++;
}
public boolean isFull(){
return usedSize == elem.length;
}
/**
* 检查add元素的时候, pos位置是否合法
* @param pos
*/
private void checkAddPos(int pos) {
if (pos < 0|| pos > usedSize) {
throw new PosIndexNotLegalException("pos位置不合法");
}
}
// 在pos位置新增元素
public void add(int pos,int data){
try {
checkAddPos(pos);
if (isFull()) {
elem = Arrays.copyOf(elem,2*elem.length);
}
for (int i = usedSize - 1; i >= pos; i--) {
elem[i + 1] = elem[i];
}
elem[pos] = data;
usedSize++;
}catch (PosIndexNotLegalException e) {
e.printStackTrace();
}
}
// 判断是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (elem[i] == toFind) {
return true;
}
}
return false;
}
// 查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (elem[i] == toFind) {
return i;
}
}
return -1;
}
private void checkGetPos(int pos) {
if (pos < 0 || pos >= usedSize) {
throw new PosIndexNotLegalException("pos位置不合法");
}
}
// 获取到pos位置的值
public int get(int pos) {
checkGetPos(pos);
return elem[pos];
}
// 给pos位置的元素设为value更新
public void set(int pos,int value) {
checkGetPos(pos);
elem[pos] = value;
}
// 删除第一次出现的关键字key
public void remove(int key) {
int index = indexOf(key);
if (index == -1) {
System.out.println("没有你要找的数字");
return;
}
for (int i = index; i < usedSize - 1; i++) {
elem[i] = elem[i + 1];
}
// 引用类型需要手动置空
// elem[i] = null;
usedSize--;
}
// 获取顺序表的长度
public int size() {
return usedSize;
}
// 清空顺序表
public void clear() {
// 引用类型需要手动置空
// for (int i = 0; i < usedSize; i++) {
// elem[i] = null;
// }
usedSize = 0;
}
}
创作于:2022年10月15日20:11:30🤣🤣