日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

看得见的数据结构Android版之数组表(数据结构篇)

發布時間:2025/3/20 Android 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 看得见的数据结构Android版之数组表(数据结构篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
零、前言:

一講到裝東西的容器,你可能習慣于使用ArrayList和數組,你有想過ArrayList和數組的區別嗎?
Java的類起名字都不是隨便亂起的,一般前面是輔助,后面是實質:ArrayList = Array + List
Array就是數組,List便是表結構,ArrayList即數組實現的表結構,問題來了,什么是表結構
注:不要問我效果圖用什么軟件畫的...因為本來就沒用什么軟件畫。下一節帶你一起自己畫!!!
希望你可以和我在Github一同見證:DS4Android的誕生與成長,歡迎star

0.不管別的,先留圖鎮樓:

表結構的常規操作

數組的擴容與縮容


1.在我們生活中都有什么表?
課程表,成績表,作息時間表、列車行程表、手表(這個算了吧...) 復制代碼
2.表有什么用?

可以把同類的對象統一管理,比如成績表: 高三12班的54為同學的成績是對象,對象又包括數學、語文、英語...等屬性 把混亂的54個對象放在一起,這么一排,哪個是學霸,哪個是學渣一目了然,非常方便 如果其中某個對象的成績改錯了,可以get到對象重新set一下,也非常方便 如果中間一個人作弊了,分數取消,直接remove掉,后面的人名詞往前排,也非常方便 如果高三12班和高三11班要比較成績,兩張表contact一下,就成一張表,合并也很方便 復制代碼
3.表和數組有什么不同?

打個最恰當的比方就是:數組相當于打印出來的紙質版而表結構像是Excel中可操作版

1.數組定長:添加新元素,定位添加都很困難 2.拿刪除來說:數組remove掉了,后面的人名次都不變----(我還沒個空白名次高,你說氣人不氣人...) 3.表是一種抽象數據類型(Abstract Data Type),既然是抽象就是規范或功能,表會有不同的實現形式 [番外]:小和尚問老和尚:"什么是圣人?" 老和尚說:"好好學習,天天向上,樂于助人,誠信友善" 這里"圣人"便是一種抽象,"好好學習,天天向上,樂于助人,誠信友善"便是"圣人""條件(功能)", 小和尚按照這么做了,他就是老和尚眼中的"圣人",即小和尚實現了圣人。4.同樣,表是一種抽象,也可以定義你眼中的表,并為它附上add(),get(),set(),remove()等功能 5.其實Java的ArrayList實現了List這個抽象接口 復制代碼
4.數組表結構:本文要務


一、定義自己的表結構

由于Java用List,為了不混淆,取了個新名字叫Chart

1.定義表的接口

也就是說說你的表能干嘛用(接口方法最好注釋非常清晰)

/*** 作者:張風捷特烈* 時間:2018/9/25 0025:8:25* 郵箱:1981462002@qq.com* 說明:線性表結構接口*/ public interface IChart<T> { //region -------------添加操作------------/*** 定點添加** @param index 索引* @param el 數據元素*/void add(int index, T el);/*** 添加尾** @param el 數據元素*/void add(T el);//endregion//region -------------刪除操作------------/*** 定位刪除** @param index 索引* @return 刪除的元素*/T remove(int index);/*** 刪除尾位** @return 刪除的元素*/T remove();/*** 刪除指定元素的第一次出現時** @param el 數據元素* @return 元素位置*/int removeEl(T el);/*** 刪除所有指定元素** @param el 數據元素*/boolean removeEls(T el);/*** 清空集合*/void clear();//endregion//region -------------改查操作------------/*** 設置某位置的元素新值** @param index 索引* @param el 新值* @return 舊值*/T set(int index, T el);/*** 根據指定位置獲取元素** @param index 索引* @return 數據元素*/T get(int index);/*** 根據指定元素獲取匹配索引** @param el 數據元素* @return 索引集*/int[] getIndex(T el); //endregion//region ------------其他操作-------------/*** 集合是否包含某元素** @param el 數據元素* @return 是否包含*/public boolean contains(T el);/*** 連接兩個集合** @param iChart 插入集合* @return 合并后的集合*/public IChart<T> contact(IChart<T> iChart);/*** 定點連接兩個集合** @param index 索引* @param iChart 插入集合* @return 合并后的集合*/IChart<T> contact(int index, IChart<T> iChart);/*** 是否為空** @return 是否為空*/boolean isEmpty();/*** 返回集合大小** @return 大小*/int size();/*** 獲取數組容量* @return 數組容量*/int capacity();//endregion } 復制代碼
2.使用數組實現表結構:ArrayChart

實現接口,并實現接口里的所有方法

/*** 作者:張風捷特烈<br/>* 時間:2018/11/21 0021:8:18<br/>* 郵箱:1981462002@qq.com<br/>* 說明:數組實現線性表結構*/ public class ArrayChart<T> implements IChart<T> {//空實現---略 } 復制代碼
3.成員變量和構造初始化
private int size;//表中數據的個數 private T[] data;//數據核心承載體 private static final int DEFAULT_CAPACITY = 10;//默認數組容量 private static final float GROW_RATE = 1.5f;//擴容增長率public ArrayChart() {this(DEFAULT_CAPACITY);//無參構造默認創建10個容量的數組 } public ArrayChart(int capacity) {data = (T[]) new Object[capacity];//新創建[數組表]時初始化數組 } 復制代碼
4.簡單接口的實現:
@Override public boolean isEmpty() {return size == 0; }@Override public int size() {return size; }@Override public int capacity() {return data.length; } 復制代碼

二、主要方法的實現(CRUD)

1.定點添加元素:

看一下操作圖(將在下一篇:視圖篇完成):默認添加到尾部
思路:定點后的所有元素后移一位,空出頂點位,讓待添加元素入駐
紫色框代表空的數組位,中間填充的是表中的實際元素
可見定點添加是在選中索引的前一位添加,所以添加到尾部是add(size,data)來添加

@Override public void add(T el) {add(size , el);//這里size---是因為在size之前一位添加 }@Override public void add(int index, T el) {if (index < 0 || index > size) {throw new IllegalArgumentException("Add failed! Make sure index < 0 || index > size");}//從最后一個元素開始,到定點位置元素,元素都后移一位for (int i = size - 1; i >= index; i--) {data[i + 1] = data[i];}data[index] = el;size++; } 復制代碼


2.查找與設置值:get(),set():

@Overridepublic T set(int index, T el) {if (index < 0 || index >= size) {throw new IllegalArgumentException("Set failed! Make sure index < 0 || index > size");}T oldEl = get(index);data[index] = el;//設置一下,很簡單return oldEl;}@Overridepublic T get(int index) {if (index < 0 || index >= size) {throw new IllegalArgumentException("Get failed! Make sure index < 0 || index > size");}return data[index];//查詢數組的對應索引處} 復制代碼

定值查詢獲取索引

@Override public int[] getIndex(T el) {int[] tempArray = new int[size];//臨時數組int count = 0;//重復個數for (int i = 0; i < size; i++) {//遍歷集合,獲取該元素重復個數,及位置數組if (data[i].equals(el)) {tempArray[count] = i;count++;}}//將臨時數組壓縮---排除空位int[] indexArray = new int[count];for (int i = 0; i < count; i++) {indexArray[i] = tempArray[i];}return indexArray;//返回查找元素的索引數組(相當于成績表看數學80分的都有哪些人) } 復制代碼
3.刪除元素:

@Override public T remove() {return remove(size - 1); }@Override public T remove(int index) {if (index < 0 || index >= size) {throw new IllegalArgumentException("Remove failed! Make sure index < 0 || index > size");}T temp = get(index);//從刪除元素索引的下一位開始到結尾,依次左移// 可簡寫: System.arraycopy(data, index + 1, data, index + 1 - 1, size - index + 1);for (int i = index + 1; i < size; i++) {data[i - 1] = data[i];}size--;//置空--游蕩的對象data[size] = null;return temp; } 復制代碼

其他刪除: 定元素刪除單個和定元素刪除所有相當于前面的組合操作,就不做操作演示了

@Override public int removeEl(T el) {int[] indexes = getIndex(el);//查找元素的索引集合,刪除首個int index = -1;if (indexes.length > 0) {index = indexes[0];remove(indexes[0]);}return index; } @Override public boolean removeEls(T el) { //查找元素的索引集合,刪除所有int[] indexArray = getIndex(el);if (indexArray.length != 0) {for (int i = 0; i < indexArray.length; i++) {remove(indexArray[i] - i); // 注意-i}return true;}return false; } 復制代碼

三、動態擴容與縮容的實現

也沒有什么高大上的,就是一個籃子裝不下了,裝個更大的籃子裝而已

1.擴容與縮容方法的實現
/*** 擴容/縮容** @param newCapacity 新容量*/ private void grow(int newCapacity) {T[] newData = (T[]) new Object[newCapacity];//創建個大籃子for (int i = 0; i < size; i++) {//把原來的元素放到大籃子里newData[i] = data[i];}data = newData; } 復制代碼
2.擴容和縮容的調用契機

什么時候擴容----籃子不夠裝了唄---add
什么時候需要縮容----1000個容量的籃子裝1個雞蛋想想也浪費---remove

1) add檢測擴容時機:滿了
@Override public void add(int index, T el) {if (size == data.length) {//籃子裝不下了---grow((int) (GROW_RATE * data.length));//換個1.5倍的籃子}if (index < 0 || index > size) {throw new IllegalArgumentException("Add failed! Make sure index < 0 || index > size");}//從最后一個元素開始,到定點位置元素,元素都后移一位//可簡寫:System.arraycopy(data, index, data, index + 1, size - index);for (int i = size - 1; i >= index; i--) {data[i + 1] = data[i];}data[index] = el;size++; } 復制代碼
2)remove檢測縮容時機

這里的判斷標志是留多點備用,不然有可能插入移除頻繁而導致重復擴容或縮容,
籃子可能會說:"你到底縮還是放,你是不是在玩老子....,老子給你多留點空行了吧!"

@Override public T remove(int index) {if (index < 0 || index >= size) {throw new IllegalArgumentException("Remove failed! Make sure index < 0 || index > size");}T temp = get(index);//從刪除元素索引的下一位開始到結尾,依次左移// 可簡寫: System.arraycopy(data, index + 1, data, index + 1 - 1, size - index + 1);for (int i = index + 1; i < size; i++) {data[i - 1] = data[i];}size--;//置空--游蕩的對象data[size] = null;//縮容----此處限定是為了避免反復出現擴容縮容---可自定義if (size == data.length / 4 && data.length / 2 != 0 && data.length > 5) {grow(data.length / 2);}return temp; } 復制代碼
3.清空時,數組縮放到初始值
@Override public void clear() {size = 0;grow(DEFAULT_CAPACITY); } 復制代碼

四、其他操作

1.是否包含某元素
@Overridepublic boolean contains(T el) {return getIndex(el).length != 0;//按值查詢有數據} 復制代碼
2.contact連接數組

@Override public IChart<T> contact(IChart<T> iChart) {return contact(size - 1, iChart); }@Override public IChart<T> contact(int index, IChart<T> iChart) {if (!(iChart instanceof ArrayChart)) {//必須是數組才能聯合return null;}//從index處遍歷本數組,將待插入數據一個一個插入for (int i = index; i < index + iChart.size(); i++) {add(i + 1, iChart.get(i - index));}return this; } 復制代碼

作為一個表結構,基本上就演示這么多,還有其他操作可以自定義接口,自己實現,
不過不管多么復雜的操作都是以上操作的組合而已。


五、小結:

關于復雜度的分析,等到所有表結構講完再整體比較一下,這里先粗略感覺一下

耗時測試
方法\操作次數10001000010W100W1000W
add首0.0063秒0.2706秒19.5379秒--------
add尾0.0004秒0.0025秒0.0141秒0.0687秒1.26014秒
remove首0.0063秒0.2771秒19.7902秒--------
remove尾0.0005秒0.0036秒0.0091秒0.02301秒:0.1607秒

可以看出往開始添加/刪除會很困難,從代碼中可以感覺到,畢竟要讓后面所有人挪一挪
想一下如果30000人排一起,第一個人走了,后面所有人往前挪一下,是不是工程量挺大的
要是你決定插到第一個,讓后面的人都往后移一下.....(大哥,活著難道不好嗎....)
所以頻繁對第一個元素進行操作的,還是不要作死,數組表結構(ArrayList)不適合你


本系列后續更新鏈接合集:(動態更新)

  • 看得見的數據結構Android版之開篇前言
  • 看得見的數據結構Android版之數組表(數據結構篇)
  • 看得見的數據結構Android版之數組表(視圖篇)
  • 看得見的數據結構Android版之單鏈表篇
  • 看得見的數據結構Android版之雙鏈表篇
  • 看得見的數據結構Android版之棧篇
  • 看得見的數據結構Android版之隊列篇
  • 看得見的數據結構Android版之二分搜索樹篇
  • 更多數據結構---以后再說吧

后記:捷文規范

1.本文成長記錄及勘誤表
項目源碼日期備注
V0.1--github2018-11-21看得見的數據結構Android版之表的數組實現(數據結構篇)
2.更多關于我
筆名QQ微信愛好
張風捷特烈1981462002zdl1994328語言
我的github我的簡書我的掘金個人網站
3.聲明

1----本文由張風捷特烈原創,轉載請注明
2----歡迎廣大編程愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這里,我在此感謝你的喜歡與支持


總結

以上是生活随笔為你收集整理的看得见的数据结构Android版之数组表(数据结构篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。