1:鏈表與數組
2:隊列和棧,出棧與入棧
3:鏈表的刪除,插入,反向
4:字符串操作
5:hash表的hash函數,衝突解決方法有哪些?
①.開放定址法
線性探測再散列
二次探測再散列
僞隨機探測再散列
②.再哈希法
這種方法是同時構造多個不同的哈希函數
③.鏈地址法 (java的HashMap採用這種方法)
④.建立一個公共溢出區
將哈希表分爲基本表和溢出表兩部分,凡是和基本表發生衝突的元素,一律填入溢出表
6:排序的原理,平均時間複雜度,最壞時間複雜度,空間複雜度,是否穩定
冒泡:平均時間複雜度爲 O(n2),空間複雜度 O(1) 選擇:平均時間複雜度爲 O(n2), 空間複雜度 O(1) 插入:平均時間複雜度爲 O(n2), 空間複雜度 O(1) 希爾:對插入排序,數據量巨大的時候, 平均時間複雜度爲 O(nlog2n), 空間複雜度 O(1) |
|
(1) 將數的個數設置爲n,取奇數k = n/2,
(2) 將差值爲K的數分爲一組,構成有序序列
(3) 再取k = k/2,將差值爲K的數分爲一組,構成有序序列
(4) 重複3直到K=1執行插入排序
快排:要求時間最快時,平均時間複雜度爲 O(nlog2n), 空間複雜度 O(nlog2n) |
(1) 選擇第一個數爲P,小於P的放在左邊,大於P的放在右邊
(2) 遞歸的將P左邊的和右邊的都按照(1)直到不能遞歸
歸併:速度僅次於快排,內存小的時候使用,可以進行並行計算的時候使用,O(nlog2n), 空間複雜度 O(n) |
(1)選擇相鄰的兩個數組成一個有序數列
(2)選擇相鄰的兩個有序數列成一個有序數列
(3)重複第二步
堆排:
(1)建堆
(2)調整堆
基數:
用於大量數,很長的數進行排序
7:快排的parition函數與歸併的Merge函數
private static int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; // 數組的第一個作爲中軸
while (low < high) {
while (low < high && list[high] >= tmp) {
high--;
}
list[low] = list[high]; // 比中軸小的記錄移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; // 比中軸大的記錄移到高端
}
list[low] = tmp; // 中軸記錄到尾
return low; // 返回中軸的位置
}
public static void merge(int[] data, int left, int center, int right) {
int[] tmpArr = new int[data.length];// 臨時數組
int mid = center + 1;// 右數組第一個元素索引
int third = left;// third 記錄臨時數組的索引
int tmp = left;// 緩存左數組第一個元素的索引
while (left <= center && mid <= right) {
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩餘部分依次放入臨時數組(實際上兩個while只會執行其中一個)
while (mid <= right)
tmpArr[third++] = data[mid++];
while (left <= center)
tmpArr[third++] = data[left++];
// 將臨時數組中的內容拷貝回原數組中
// (原left-right範圍的內容被複制回原數組)
while (tmp <= right)
data[tmp] = tmpArr[tmp++];
}
8:對冒泡與快排的改進
9:二分查找,與變種的二分查找
二分查找: mid=low+(high-low)/2
變種二分查找:
插值查找二分查找:
mid=low+(key-a[low])/(a[high]-key)*(high-low)
斐波那契查找算法:
mid=low+F(k?1)?1
10:二叉樹
11:AVL樹(平衡二叉樹的一種)
絕對的平衡二叉樹,不過增刪的操作複雜度過高,應用不如紅黑樹廣
LL:某一節點的左孩子的左子樹上插入一個新的節點,使得該節點不再平衡。這時只需要把樹向右旋轉一次即可
RR:某一節點的右孩子的右子樹上插入一個新的節點,使得該節點不再平衡。這時只需要把樹向左旋轉一次即可
LR:某一節點的左孩子的右子樹上插入一個新的節點,使得該節點不再平衡。這時需要旋轉兩次,左旋+右旋
RL:某一節點的右孩子的左子樹上插入一個新的節點,使得該節點不再平衡。這時需要旋轉兩次,右旋+左旋
12:紅黑樹(平衡二叉樹的一種)
(1)每個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每個葉子節點(NIL)是黑色。 [注意:這裏葉子節點,是指爲空(NIL或NULL)的葉子節點!]
(4)如果一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。
左旋:對x進行左旋,意味着 將x變成一個左節點
右旋:對x進行右旋,意味着 將x變成一個右節點
添加:第一步: 將紅黑樹當作一顆二叉查找樹,將節點插入。
第二步:將插入的節點着色爲"紅色"。
第三步: 通過一系列的旋轉或着色等操作,使之重新成爲一顆紅黑樹。
刪除:第一步:將紅黑樹當作一顆二叉查找樹,將節點刪除。
第二步:通過"旋轉和重新着色"等一系列來修正該樹,使之重新成爲一棵紅黑樹。
13 Treap(樹堆)
14:哈夫曼樹
15:二叉樹的前中後續遍歷,遞歸非遞歸寫法,層序遍歷算法
遞歸是自己調用自己
非遞歸是使用堆棧
16:KMP算法
17:排列組合問題
18:動態規劃,貪心算法,分治算法
19:跳錶的數據結構
一種可以代替平衡樹的數據結構