Java數(shù)據(jù)結(jié)構(gòu)之順序表的實現(xiàn)
一. 線性表中的順序表
線性表(linear list)是n個具有相同特性的數(shù)據(jù)元素的有限序列。 線性表是一種在實際中廣泛使用的數(shù)據(jù)結(jié)構(gòu),常見的線性表:順序表、鏈表、棧、隊列…
線性表在邏輯上是線性結(jié)構(gòu),也就說是連續(xù)的一條直線。但是在物理結(jié)構(gòu)上并不一定是連續(xù)的,線性表在物理上存儲時,通常以數(shù)組和鏈?zhǔn)浇Y(jié)構(gòu)的形式存儲。

順序表是用一段物理地址連續(xù)的存儲單元依次存儲數(shù)據(jù)元素的線性結(jié)構(gòu),一般情況下采用數(shù)組存儲。在數(shù)組上完成數(shù)據(jù)的增刪查改。
二. 順序表的全局實現(xiàn)
MyArrayLisst.java
import java.util.Arrays;
public class MyArrayList {
private int[] elem;//數(shù)組
private int usedSize;//記錄有效數(shù)據(jù)個數(shù)
private static final int DEFAYLT_SIZE = 10;
//構(gòu)造方法
public MyArrayList() {
this.elem = new int[DEFAYLT_SIZE];
}
// 打印順序表
//注意:該方法并不是順序表中的方法,為了方便看測試結(jié)果給出的
public void display() {
for (int i = 0; i < this.size(); i++) {
System.out.print(this.elem[i] + " ");
}
}
// 新增元素,默認在數(shù)組最后新增
public void add(int data) {
//1.判斷數(shù)組是否滿了
if(Full()) {
System.out.println("空間滿!");
//2.滿了進行擴容
this.elem = Arrays.copyOf(this.elem, 2*this.elem.length);
System.out.println("擴容完成!");
}
//3.將數(shù)據(jù)放入
this.elem[this.usedSize] = data;
//4.更新有效數(shù)據(jù)個數(shù)
this.usedSize++;
}
//1.
public boolean Full() {
return this.size() >= this.elem.length;
}
// 在 pos 位置新增元素
public void add(int pos, int data) throws PosWrongfulException{
//1.判斷數(shù)組是否滿了
if(Full()) {
System.out.println("空間滿!");
//2.滿了進行擴容
this.elem = Arrays.copyOf(this.elem, 2*this.elem.length);
System.out.println("擴容完成!");
}
//判斷pos位置是否合法,不合法拋出異常
if(pos < 0 || pos > this.usedSize) {
//拋出自定義異常,要注意去聲明異常以便繼續(xù)拋出
throw new PosWrongfulException("add參數(shù)中,pos位置不合法");
}
//pos合法,從pos位置開始的元素向都后挪一個位置,讓pos位置空出來
for (int i = this.usedSize; i >= pos; i--) {
this.elem[i+1] = this.elem[i];
}
//在pos位置插入數(shù)據(jù)
this.elem[pos] = data;
//更新有效數(shù)據(jù)個數(shù)
this.usedSize++;
}
// 判定是否包含某個元素
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if(elem[i] == toFind)
return true;
}
return false;
}
// 查找某個元素對應(yīng)的位置
public int indexOf(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if(elem[i] == toFind)
return i;
}
return -1;
}
// 獲取 pos 位置的元素
public int get(int pos) throws EmptyException{
//判斷順序表是否為空
if(isEmpty()) {
throw new EmptyException("當(dāng)前順序表為空!");
}
//判斷pos是否合法
if(pos < 0 || pos >= this.usedSize) {
//拋出自定義異常,要注意去聲明異常以便繼續(xù)拋出
throw new PosWrongfulException("get獲取元素時,pos位置不合法");
}
return this.elem[pos];
}
public boolean isEmpty() {
return this.size() == 0;
}
// 給 pos 位置的元素設(shè)為 value
public void set(int pos, int value) {
//判斷順序表是否為空
if(isEmpty()) {
throw new EmptyException("當(dāng)前順序表為空!");
}
//判斷pos是否合法
if(pos < 0 || pos >= this.usedSize) {
//拋出自定義異常,要注意去聲明異常以便繼續(xù)拋出
throw new PosWrongfulException("set設(shè)置元素時,pos位置不合法");
}
this.elem[pos] = value;
}
//刪除第一次出現(xiàn)的關(guān)鍵字key
public void remove(int toRemove) {
//判斷順序表是否為空
if(isEmpty()) {
throw new EmptyException("當(dāng)前順序表為空!");
}
//查找要刪除元素的位置
int index = this.indexOf(toRemove);
if(index == -1) {
System.out.println("沒有你要刪除的元素"+toRemove);
return;
}
//刪除元素,從后往前進行覆蓋
for (int i = index; i < this.size(); i++) {
this.elem[i] = this.elem[i+1];
}
//更新有效數(shù)據(jù)個數(shù)
this.usedSize--;
}
// 獲取順序表長度
public int size() {
return this.usedSize;
}
// 清空順序表
public void clear() {
this.usedSize = 0;
}
}
EmptyException.java(空指針異常)
public class EmptyException extends RuntimeException{
public EmptyException() {
}
public EmptyException(String message) {
super(message);
}
}
PosWrongfulException.java(越界異常)
public class EmptyException extends RuntimeException{
public EmptyException() {
}
public EmptyException(String message) {
super(message);
}
}
TestList.java(測試部分)
public class TestList {
public static void main(String[] args) {
MyArrayList myArrayList = new MyArrayList();
System.out.println("在順序表最后一個位置添加元素");
myArrayList.add(1);
myArrayList.add(2);
myArrayList.add(3);
myArrayList.add(4);
myArrayList.display();
System.out.println();
System.out.println("插入元素");
try {
myArrayList.add(0,6);
myArrayList.add(6,10);
} catch (PosWrongfulException e) {
e.printStackTrace();
}
myArrayList.display();
System.out.println();
System.out.println("順序表是否包含某個元素");
System.out.println(myArrayList.contains(2));
System.out.println(myArrayList.contains(66));
System.out.println("獲取元素位置");
System.out.println(myArrayList.indexOf(3));
System.out.println(myArrayList.indexOf(88));
System.out.println("獲取pos位置的元素");
try {
System.out.println(myArrayList.get(1));
System.out.println(myArrayList.get(10));
}catch (PosWrongfulException e) {
e.printStackTrace();
}
System.out.println("更改pos位置的元素值");
try {
myArrayList.set(0,99);
myArrayList.set(10,10);
}catch (PosWrongfulException e) {
e.printStackTrace();
}
myArrayList.display();
System.out.println();
System.out.println("刪除第一次出現(xiàn)的數(shù)值");
myArrayList.remove(3);
myArrayList.remove(999);
myArrayList.display();
System.out.println();
System.out.println("清空順序表后再添加一個元素");
myArrayList.clear();
myArrayList.add(666);
myArrayList.display();
}
}
測試結(jié)果


三. 順序表功能的具體分析
1. 順序表的定義
順序表本質(zhì)上是基于數(shù)組進行操作的, 所以順序表成員中定義一個數(shù)組elem來存放數(shù)據(jù), 這里的順序表實現(xiàn)以整形為例, 順序表中的元素可以是其他類型,實現(xiàn)方法類似.
定義變量usedSize用來記錄順序表中的元素個數(shù); 定義常量并給出構(gòu)造方法以方便在創(chuàng)建順序表時給數(shù)組分配默認空間.
public class MyArrayList {
private int[] elem;//數(shù)組
private int usedSize;//記錄有效數(shù)據(jù)個數(shù)
private static final int DEFAYLT_SIZE = 10;
//構(gòu)造方法
public MyArrayList() {
this.elem = new int[DEFAYLT_SIZE];
}
}
2. 獲取順序表長度
獲取順序表中記錄數(shù)組中有效數(shù)據(jù)個數(shù)的成員即可
public int size() {
return this.usedSize;
}
3. 新增元素,在數(shù)組最后添加
在添加元素前要判斷數(shù)組空間是否滿了, 如果滿了要先進行擴容然后再添加, 添加成功后要記得更新數(shù)據(jù)的有效個數(shù)
public void add(int data) {
//1.判斷數(shù)組是否滿了
if(Full()) {
System.out.println("空間滿!");
//2.滿了進行擴容
this.elem = Arrays.copyOf(this.elem, 2*this.elem.length);
System.out.println("擴容完成!");
}
//3.將數(shù)據(jù)放入
this.elem[this.usedSize] = data;
//4.更新有效數(shù)據(jù)個數(shù)
this.usedSize++;
}
//1.
public boolean Full() {
return this.size() >= this.elem.length;
}4. 在指定位置插入元素
先判斷數(shù)組空間是不是滿了, 然后判斷要插入位置的法性, 注意插入數(shù)據(jù)只能在以經(jīng)存放了數(shù)劇的范圍內(nèi)進行插入, 也就是插入的位置相鄰位置要有元素, 不能空著插;
如果位置不合法, 為了使出現(xiàn)問題的地方更突出以便于追蹤和解決問題, 我們可以讓報異常來達到目的, 我們?nèi)プ远x異常, 如果位置不合法拋出異常, 讓程序進行捕獲和處理.
添加成功后要記得更新數(shù)據(jù)的有效個數(shù), 異常的實現(xiàn)在上文中已經(jīng)給出.
public void add(int pos, int data) throws PosWrongfulException{
//1.判斷數(shù)組是否滿了
if(Full()) {
System.out.println("空間滿!");
//2.滿了進行擴容
this.elem = Arrays.copyOf(this.elem, 2*this.elem.length);
System.out.println("擴容完成!");
}
//判斷pos位置是否合法,不合法拋出異常
if(pos < 0 || pos > this.usedSize) {
//拋出自定義異常,要注意去聲明異常以便繼續(xù)拋出
throw new PosWrongfulException("add參數(shù)中,pos位置不合法");
}
//pos合法,從pos位置開始的元素向都后挪一個位置,讓pos位置空出來
for (int i = this.usedSize; i >= pos; i--) {
this.elem[i+1] = this.elem[i];
}
//在pos位置插入數(shù)據(jù)
this.elem[pos] = data;
//更新有效數(shù)據(jù)個數(shù)
this.usedSize++;
}5. 判斷是否包含某個元素
遍歷數(shù)組將每個元素逐一比較即可
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if(elem[i] == toFind)
return true;
}
return false;
}
6. 查找某個元素所在位置
遍歷數(shù)組比較即可
public int indexOf(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if(elem[i] == toFind)
return i;
}
return -1;
}
7. 獲取指定位置的元素
如果順序表中沒有存放元素的話是不能去獲取元素的, 這里同樣可以去聲明一個異常去解決問題; 同時要判斷位置的合法性,
上面兩個條件都沒問題的話就可以通過下標(biāo)去獲取元素了
public int get(int pos) throws EmptyException{
//判斷順序表是否為空
if(isEmpty()) {
throw new EmptyException("當(dāng)前順序表為空!");
}
//判斷pos是否合法
if(pos < 0 || pos >= this.usedSize) {
//拋出自定義異常,要注意去聲明異常以便繼續(xù)拋出
throw new PosWrongfulException("get獲取元素時,pos位置不合法");
}
return this.elem[pos];
}
8. 修改指定位置的元素
和6中的代碼屬于一份代碼, 在最后將獲取元素返回改為賦值即可
public void set(int pos, int value) {
//判斷順序表是否為空
if(isEmpty()) {
throw new EmptyException("當(dāng)前順序表為空!");
}
//判斷pos是否合法
if(pos < 0 || pos >= this.usedSize) {
//拋出自定義異常,要注意去聲明異常以便繼續(xù)拋出
throw new PosWrongfulException("set設(shè)置元素時,pos位置不合法");
}
this.elem[pos] = value;
??????? }
9. 刪除第一次出現(xiàn)的元素key
判斷順序表是否為空, 不為空則先找到要刪除元素的位置, 將key之后的元素逐一往前覆蓋, 將key覆蓋便達到了刪除的效果; 最后要記得元素的有效個數(shù)要減1;
需要注意的是,這里刪除的基本數(shù)據(jù)類型的數(shù)據(jù), 刪除后相對于刪除前數(shù)組的最后一個位置, 雖然那個位置還留有原來的值, 但這個值不置為0并不會有什么影響;
而如果順序表中放置的是引用類型, 此時這個位置必須置空(置為null), 否則會有內(nèi)存泄漏的問題存在.
public void remove(int toRemove) {
//判斷順序表是否為空
if(isEmpty()) {
throw new EmptyException("當(dāng)前順序表為空!");
}
//查找要刪除元素的位置
int index = this.indexOf(toRemove);
if(index == -1) {
System.out.println("沒有你要刪除的元素"+toRemove);
return;
}
//刪除元素,從后往前進行覆蓋
for (int i = index; i < this.size(); i++) {
this.elem[i] = this.elem[i+1];
}
//更新有效數(shù)據(jù)個數(shù)
this.usedSize--;
}10. 清空順序表
將數(shù)組的有效元素個數(shù)賦值為0即可;
同樣的, 要注意如果順序表中的元素是引用類型的話, 要將數(shù)組中的每個元素都置為null.
public void clear() {
this.usedSize = 0;
}
11. 打印順序表(不屬于順序表功能)
遍歷數(shù)組打印即可, 要注意的是順序表中是沒有這個功能的, 只是為了測試, 方便觀察調(diào)試所設(shè).
public void display() {
for (int i = 0; i < this.size(); i++) {
System.out.print(this.elem[i] + " ");
}
}以上就是Java數(shù)據(jù)結(jié)構(gòu)之順序表的實現(xiàn)的詳細內(nèi)容,更多關(guān)于Java順序表的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
DOM解析XML報錯Content is not allowed in prolog解決方案詳解
這篇文章主要介紹了DOM解析XML報錯解決方案詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
intellij idea快速查看當(dāng)前類中的所有方法(推薦)
這篇文章主要介紹了intellij idea快速查看當(dāng)前類中的所有方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
Java創(chuàng)建型設(shè)計模式之工廠方法模式深入詳解
工廠方法模式(FACTORY METHOD)是一種常用的類創(chuàng)建型設(shè)計模式,此模式的核心精神是封裝類中變化的部分,提取其中個性化善變的部分為獨立類,通過依賴注入以達到解耦、復(fù)用和方便后期維護拓展的目的。它的核心結(jié)構(gòu)有四個角色,分別是抽象工廠、具體工廠、抽象產(chǎn)品、具體產(chǎn)品2022-09-09
java后臺實現(xiàn)支付寶支付接口和支付寶訂單查詢接口(前端為APP)
這篇文章主要介紹了java后臺實現(xiàn)支付寶支付接口和支付寶訂單查詢接口(前端為APP),非常具有實用價值,需要的朋友可以參考下2018-08-08
springboot實現(xiàn)FastJson解析json數(shù)據(jù)的方法
本篇文章主要介紹了springboot實現(xiàn)FastJson解析json數(shù)據(jù)的方法,非常具有實用價值,需要的朋友可以參考下2017-04-04

