數(shù)據(jù)結(jié)構(gòu)Java源碼分析

參考書籍《大話數(shù)據(jù)結(jié)構(gòu)》,實現(xiàn)參考JDK1.8

線性表:

Java實現(xiàn)類有ArrayList,LinkedList

ArrayList:

動態(tài)容量數(shù)組的列表旋炒,擴(kuò)展類有序數(shù)組
int size;//數(shù)據(jù)大小
Object[] data;//容量數(shù)組
默認(rèn)數(shù)組是空數(shù)組霎桅,容量為0旅择,默認(rèn)增加容量值是10,DEFAULT_CAPACITY

擴(kuò)容規(guī)則:傳入擴(kuò)容值為minCapacity预麸,若當(dāng)前數(shù)組是空數(shù)組瞪浸,擴(kuò)容值為max(minCapacity,DEFAULT_CAPACITY),否則判斷minCapacity - size吏祸,若大于0默認(rèn)將當(dāng)前容量 + 當(dāng)前容量擴(kuò)大2倍為newCapacity对蒲,newCapacity若小于minCapacity,容量值為minCapacity贡翘,否則為newCapacity蹈矮,然后進(jìn)行數(shù)組拷貝生成新數(shù)組。

添加/插入:添加時先檢查是否需要擴(kuò)容鸣驱,然后給size+1賦值泛鸟,插入操作是檢查插入位置是否在范圍,不在范圍就拋異常踊东,在范圍進(jìn)行檢查是否需要擴(kuò)容北滥,然后進(jìn)行數(shù)據(jù)移動拷貝arraycopy(data,index,data,index+1,size - index),data[size++] = o闸翅,底層C實現(xiàn)再芋,時間復(fù)雜度O(n)
刪除:檢查刪除位置是否在范圍,然后再進(jìn)行數(shù)據(jù)移動拷貝(data,index + 1,data,index - 1, size - index - 1)坚冀,data[--size] = null
查找/搜索:指定位置查找济赎,O(1),對象查找indexOf(Object) 順序查找O(n),
排序:冒泡排序O(n^2)
優(yōu)缺點:順序儲存司训,索引查找快构捡,增刪慢

LinkedList(實現(xiàn)了Deque雙端隊列接口):

鏈表:動態(tài)容量的雙向鏈?zhǔn)搅斜恚瑪U(kuò)展類有單向鏈表豁遭,循環(huán)鏈表叭喜,雙向鏈表,靜態(tài)鏈表

int size;//數(shù)據(jù)大小
Node<E> first;//頭節(jié)點
Node<E> last;//尾節(jié)點

class Node<E>{
E item;//數(shù)據(jù)元素
Node<E> prev;//節(jié)點前驅(qū)
Node<E> next;//節(jié)點后驅(qū)
}
默認(rèn)是空鏈表蓖谢,容量為0

擴(kuò)容規(guī)則:無數(shù)量限制捂蕴,添加多少元素增加多少節(jié)點,數(shù)量為size
添加/插入

//默認(rèn)添加是從尾部插入
Node l = last; 
Node newNode = (l,o,null);
last = newMode;
if(l== null) first = newNode; 
else l.next = newMode;
size++;

//頭部插入
Node l = first闪幽;
Node newNode = (null,o,l);
first = newMode; 
if(l == null) last = newMode;
else l.prev = newMode;size++;

查找/搜索:雙向鏈表通過傳入的index/2判斷從頭部還是尾部遍歷搜索啥辨,查找到節(jié)點E,次數(shù)為n/2盯腌,O(n)
刪除:remove()方法默認(rèn)刪除頭部溉知,傳入obj進(jìn)行刪除的話,步驟是先查找到節(jié)點S腕够,然后進(jìn)行鏈接清除

Node prev = s.prev;Node next = s.next;
if(prev != null){prev.next = next;s.prev=null;}else{first=next};
if(next != null){next.prev = prev;s.next=null;}else{last=next};
s.item = null;
size--;

具有Collection的操作方法
add();
remove();

具有隊列Queue的操作方法
peek(),element();
offer();
poll();
E remove();

peek()方法取出隊列頭部元素時候级乍,不刪除該元素,而poll()方法取出元素時會刪除元素帚湘。如果遇到隊列為空的情況是玫荣,兩者都會返回null,element()會拋出異常

雙端隊列Deque(繼承隊列接口大诸,具有棧)的操作方法:
所有的操作方法peekFirst,peekLast.....
push()無空間會拋異常
pop()無元素會拋異常

優(yōu)缺點:不受固定的存儲空間限制捅厂,快速的插入和刪除操作,整塊集合插入為O(1)资柔,查詢效率比順序列表低焙贷,O(n)

棧和隊列:

棧是限定僅在表尾進(jìn)行插入和刪除操作的線性表
隊列是只允許在一端進(jìn)行插入操作,在另一端進(jìn)行刪除操作的線性表

棧/隊列的二種實現(xiàn):數(shù)組實現(xiàn)棧贿堰,隊列辙芍,鏈表實現(xiàn)簡述(見上面LinkedList)
ArrayDeque

object[] elements;//元素數(shù)組
int head;//頭部數(shù)據(jù)的位置索引
int tail;//尾部數(shù)據(jù)的位置索引

擴(kuò)容規(guī)則:默認(rèn)長度16,傳入值會轉(zhuǎn)換成2^n官边,當(dāng)頭部head == tail時沸手,說明沒有位置可以儲存數(shù)據(jù),進(jìn)行擴(kuò)容2倍注簿,然后將數(shù)據(jù)拷貝到新數(shù)組頭部契吉,head重新賦值0,tail賦值為原來的數(shù)組長度n

private void doubleCapacity() {
        assert head == tail;
        int p = head;
        int n = elements.length;
        int r = n - p; // number of elements to the right of p
        int newCapacity = n << 1;
        if (newCapacity < 0)
            throw new IllegalStateException("Sorry, deque too big");
        Object[] a = new Object[newCapacity];
        System.arraycopy(elements, p, a, 0, r);
        System.arraycopy(elements, 0, a, r, p);
        elements = a;
        head = 0;
        tail = n;
    }

添加/插入:設(shè)置后檢測是否需要擴(kuò)容

public void addFirst(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;
        if (head == tail)
            doubleCapacity();
    }

 public void addLast(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[tail] = e;
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
            doubleCapacity();
    }

刪除:刪除前后元素時間復(fù)雜度為O(1)诡渴,然后修改head或者tail捐晶,刪除對象會遍歷數(shù)組O(n)菲语,找到相應(yīng)下標(biāo),然后移動拷貝整個數(shù)組
查找/搜索:獲取前后元素為O(1)
排序:無
優(yōu)缺點:查找元素惑灵,刪除前后元素效率高山上,刪除其他位置O(n)

棧(LIFO,FILO)常用方法是void push(),E pop()英支,操作失敗拋出異常佩憾,默認(rèn)調(diào)用的是addFirst,removeFirst
隊列(FIFO)常用方法是boolean offer(E)干花,E poll()妄帘,操作失敗返回false,null池凄,默認(rèn)調(diào)用的是addLast抡驼,pollFirst

零個或多個字符組成的有限序列
String

char[] value;//字符數(shù)組
int hash;//hash值

固定長度,構(gòu)造方法不傳如數(shù)組或串肿仑,默認(rèn)為空串""致盟,不可變類,操作形成新的String對象

操作方法:
String(char[] arr)
String(String str)
String(byte[] bytes)
length()
getChars(char[] buf,int len)
isEmpty()
charAt(int index)
compareTo
startWith
indexOf
subString
replaceAll
split
concat

startWith尤慰,endWitdh
偏移length進(jìn)行普通匹配算法O(n-m+1)

indexOf
普通匹配算法O(n-m+1)*m馏锡,KMP子串匹配算法O(n+m)

replaceAll
正則匹配實現(xiàn)

HashMap KV對集合,字典

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伟端,一起剝皮案震驚了整個濱河市眷篇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荔泳,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虐杯,死亡現(xiàn)場離奇詭異玛歌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)擎椰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門支子,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人达舒,你說我怎么就攤上這事值朋。” “怎么了巩搏?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵昨登,是天一觀的道長。 經(jīng)常有香客問我贯底,道長丰辣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮笙什,結(jié)果婚禮上飘哨,老公的妹妹穿的比我還像新娘。我一直安慰自己琐凭,他們只是感情好芽隆,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著统屈,像睡著了一般胚吁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸿吆,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天囤采,我揣著相機(jī)與錄音,去河邊找鬼惩淳。 笑死蕉毯,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的思犁。 我是一名探鬼主播代虾,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼激蹲!你這毒婦竟也來了棉磨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤学辱,失蹤者是張志新(化名)和其女友劉穎乘瓤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體策泣,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡衙傀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了萨咕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片统抬。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖危队,靈堂內(nèi)的尸體忽然破棺而出聪建,到底是詐尸還是另有隱情,我是刑警寧澤茫陆,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布金麸,位于F島的核電站,受9級特大地震影響盅弛,放射性物質(zhì)發(fā)生泄漏钱骂。R本人自食惡果不足惜叔锐,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望见秽。 院中可真熱鬧愉烙,春花似錦、人聲如沸解取。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽禀苦。三九已至蔓肯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間振乏,已是汗流浹背蔗包。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留慧邮,地道東北人调限。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像误澳,于是被迫代替她去往敵國和親耻矮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容