鏈表和數(shù)組的區(qū)別
從邏輯結(jié)構(gòu)來看
- 數(shù)組必須事先定義固定的長度,不能適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況。當(dāng)數(shù)據(jù)增加時(shí),可能超出原先定義的元素個(gè)數(shù);當(dāng)數(shù)據(jù)減少時(shí),造成內(nèi)存浪費(fèi);數(shù)組可以根據(jù)下標(biāo)直接存取。
- 鏈表動(dòng)態(tài)地進(jìn)行存儲分配,可以適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況,且可以方便地插入、刪除數(shù)據(jù)項(xiàng)。(數(shù)組中插入、刪除數(shù)據(jù)項(xiàng)時(shí),需要移動(dòng)其它數(shù)據(jù)項(xiàng),非常繁瑣)鏈表必須根據(jù)next指針找到下一個(gè)元素
從內(nèi)存存儲來看
- (靜態(tài))數(shù)組從棧中分配空間, 對于程序員方便快速,但是自由度小
- 鏈表從堆中分配空間, 自由度大但是申請管理比較麻煩
從上面的比較可以看出,如果需要快速訪問數(shù)據(jù),很少或不插入和刪除元素,就應(yīng)該用數(shù)組;相反, 如果需要經(jīng)常插入和刪除元素就需要用鏈表數(shù)據(jù)結(jié)構(gòu)了。
排序基本
作為排序依據(jù)的數(shù)據(jù)項(xiàng)稱為排序碼,也即數(shù)據(jù)元素的關(guān)鍵碼。若關(guān)鍵碼是主關(guān)鍵碼,則對于任意待排序序列,經(jīng)排序后得到的結(jié)果是唯一的;若關(guān)鍵碼是次關(guān)鍵碼,排序結(jié)果可能不唯一。
若對任意的數(shù)據(jù)元素序列,使用某個(gè)排序方法,對它按關(guān)鍵碼進(jìn)行排序:若相同關(guān)鍵碼元素間的位置關(guān)系,排序前與排序后保持一致,稱此排序方法是穩(wěn)定的;而不能保持一致的排序方法則稱為不穩(wěn)定的。
排序分為兩大類:內(nèi)排序和外排序。
- 內(nèi)排序:指待排序列完全存放在內(nèi)存中所進(jìn)行的排序過程,適合不太大的元素序列。
- 外排序:指排序過程中還需訪問外存儲器,足夠大的元素序列,因不能完全放入內(nèi)存,只能使用外排序。
插入排序
插入排序是一種簡單直觀的排序算法。它的工作原理是通過構(gòu)建有序序列,對于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入。插入排序在實(shí)現(xiàn)上,通常采用in-place排序(即只需用到O(1)的額外空間的排序),因而在從后向前掃描過程中,需要反復(fù)把已排序元素逐步向后挪位,為最新元素提供插入空間。
插入排序都采用in-place在數(shù)組上實(shí)現(xiàn),其運(yùn)作如下:
1.從第一個(gè)元素開始,該元素可以認(rèn)為已經(jīng)被排序
2.取出下一個(gè)元素,在已經(jīng)排序的元素序列中從中向前掃描
3.如果該元素(已排序)大于新元素,將該元素移到下一位置
4.重復(fù)步驟3,直到找到已排序的元素小于或等于新元素的位置
5.將新元素插入到該位置后
6.重復(fù)步驟2~5
冒泡排序
- 冒泡排序是一種簡單的排序算法。它重復(fù)地走訪過要排序的數(shù)列,一次比較兩個(gè)元素,如果他們的順序錯(cuò)誤就把他們交換過來。
運(yùn)作如下:
比較相鄰的元素。如果第一個(gè)比第二個(gè)大,就交換他們兩個(gè)。
對每一對相鄰元素作同樣的工作,從開始第一對到結(jié)尾的最后一對。這步做完后,最后的元素會(huì)是最大的數(shù)。
針對所有的元素重復(fù)以上的步驟,除了最后一個(gè)。
持續(xù)每次對越來越少的元素重復(fù)上面的步驟,直到?jīng)]有任何一對數(shù)字需要比較。
快速排序
- 通過一趟排序?qū)⒋庞涗浄指畛瑟?dú)立的兩部分,其中一部分記錄的關(guān)鍵字均比另一部分記錄的關(guān)鍵字小,則可分別對這兩部分記錄繼續(xù)進(jìn)行排序。
是冒泡排序的一種升級;
基本原理:
設(shè)定一個(gè)基準(zhǔn)值(也就是軸)
將比軸小的值,移到軸的左邊,形成左子數(shù)列
將比軸大的值,移到軸的右邊,形成右子數(shù)列
分別對左子數(shù)列和右子數(shù)列做上述三個(gè)步驟(遞歸),直到左子數(shù)列或右子數(shù)列只剩一個(gè)值或沒有數(shù)值
選擇排序
- 比如在一個(gè)長度為N的無序數(shù)組中,在第一趟遍歷N個(gè)數(shù)據(jù),找出其中最小的數(shù)值與第一個(gè)元素交換,第二趟遍歷剩下的N-1個(gè)數(shù)據(jù),找出其中最小的數(shù)值與第二個(gè)元素交換......第N-1趟遍歷剩下的2個(gè)數(shù)據(jù),找出其中最小的數(shù)值與第N-1個(gè)元素交換,至此選擇排序完成。
希爾排序
- 主要就是選定一個(gè)h的有序數(shù)組來進(jìn)行預(yù)排序。這樣最后進(jìn)行插入排序的時(shí)候,能使數(shù)據(jù)局部有序。就算交換的話,交換的次數(shù)也不會(huì)很多。這樣h序列稱為遞增序列。希爾的性能很大部分取決于遞增序列 。一般來說我們使用這個(gè)序列3x + 1.
堆排序
- 它是選擇排序的一種。可以利用數(shù)組的特點(diǎn)快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。
二叉樹
- 在二叉樹的第i層上至多有2i-1個(gè)結(jié)點(diǎn)(i≥1)。
- 深度為k的二叉樹至多有2k-1個(gè)結(jié)點(diǎn)(k≥1)。
- 遍歷二叉樹
- 先序遍歷(DLR)
⑴訪問根結(jié)點(diǎn);
⑵先序遍歷根結(jié)點(diǎn)的左子樹;
⑶先序遍歷根結(jié)點(diǎn)的右子樹。
- 中序遍歷(LDR)
⑴中序遍歷根結(jié)點(diǎn)的左子樹;
⑵訪問根結(jié)點(diǎn);
⑶中序遍歷根結(jié)點(diǎn)的右子樹。
- 后序遍歷(LRD)
⑴后序遍歷根結(jié)點(diǎn)的左子樹;
⑵后序遍歷根結(jié)點(diǎn)的右子樹。
⑶訪問根結(jié)點(diǎn);
- 層次遍歷(隊(duì)列實(shí)現(xiàn))
構(gòu)建一個(gè)隊(duì)列專門用來儲存二叉樹節(jié)點(diǎn)指針,先把根節(jié)點(diǎn)入隊(duì),假設(shè)是A,對A元素進(jìn)行訪問,然后對A的左右孩子依次入隊(duì),假設(shè)B,C。A出隊(duì)列,再是對B進(jìn)行訪問,同樣將B的左右孩子入隊(duì)列,B出對列······重復(fù)以上,知道隊(duì)列為空。
哈希
- Hashing查找,也稱為散列查找或雜湊查找。它既是一種查找方法,又是一種存貯方法,稱為散列存貯。散列存貯的內(nèi)存存放形式也稱為散列表
- 哈希函數(shù)
在記錄的關(guān)鍵字與記錄的存儲地址之間建立的一種對應(yīng)關(guān)系叫哈希函數(shù)。
哈希函數(shù)是從關(guān)鍵字空間到存儲地址空間的一種映象
哈希函數(shù)可寫成:addr(ai)=H(keyi)
ai是表中的一個(gè)元素
addr(ai)是ai的存儲地址
keyi是ai的關(guān)鍵字
- 哈希表
應(yīng)用哈希函數(shù),由記錄的關(guān)鍵字確定記錄在表中的地址,并將記錄放入此地址,這樣構(gòu)成的表叫哈希表。
- 哈希查找
又叫散列查找,利用哈希函數(shù)進(jìn)行查找的過程叫哈希查找。
- 沖突:key1?key2,但H(key1)=H(key2)的現(xiàn)象叫沖突