折半插入排序
折半插入排序在本質上還是算作插入排序,不同的是比較的次數減少,直接插入排序是從后往前一個個的去比較,而折半插入排序是折中的方式來進行比較,總體的比較次數會比直接插入排序少,代碼如下所示:
public void zbInsert() {
int[] A = {1, 2, 3, 4};
int[] B = {2, 4, 5, 6};
int[] C = new int[A.length+B.length];
/*-------------------
將較長的數組copy到新數組前面部分,
類似直接插入,減少插入預判次數------------------
*/
for (int k = 0;k<A.length+B.length;k++){
if (A.length>=B.length){
if (k<A.length)C[k] = A[k];
if (k>=A.length)C[k] = B[k-A.length];
}else {
if (k<B.length)C[k] = B[k];
if (k>=B.length)C[k] = A[k-B.length];
}
}
int j;
for (int i = A.length;i<C.length;i++){
int left = 0;
int right = i-1;
int current = C[i];
while (right>=left){
int mid = (right+left)/2;
if (C[mid]>current)
right = mid-1;
else
left = mid+1;
}
/*------------將比current大的值往后移動一位-------------*/
for (j = i-1;j>=left;j--)
C[j+1] = C[j];
/*---------------在找到的索引位置賦值---------------*/
C[j+1] = current;
}
for (int k = 0;k<C.length;k++)
System.out.print(C[k]+",");
}
小根堆的方式獲取丑數
丑數就是因子只包含2,3,5的數,算法如下,PriorityQueue隊列內部默認通過小根堆的方式進行排序。
public int method(int n) {
if (n == 1) return 1;
Queue<Integer> choushu = new PriorityQueue<>();
choushu.offer(1);
for (int i = 2; i <= n; i++) {
/*---------------小根堆的方式排序,每次poll都是彈出最小值---------------*/
int flag = choushu.poll();
if (!choushu.contains(flag * 2)) choushu.offer(flag * 2);
if (!choushu.contains(flag * 3)) choushu.offer(flag * 3);
if (!choushu.contains(flag * 5)) choushu.offer(flag * 5);
}
return choushu.poll().intValue();
}
大根堆的方式獲取第N個大的值
大根堆跟小根堆正好相反,不過priorityQueue還是提供了參數進行大根堆的方式排序。
public int kthLargestElement(int n, int[] nums) {
// write your code here
PriorityQueue<Integer> queue = new PriorityQueue<>(nums.length, Collections.reverseOrder());
int result = 0;
for (int i = 0; i < nums.length; i++) {
queue.offer(nums[i]);
}
for (int j = 0; j < n; j++)
result = queue.poll();
return result;
}
Queue隊列
稍微了解一下關于queue隊列的知識
Queue:基本上,一個隊列就是一個先入先出(FIFO)的數據結構
Queue接口與List、Set同一級別,都是繼承了Collection接口。LinkedList實現了Deque接口。
Deque(雙端隊列)
LinkedList:實現了java.util.Queue接口和java.util.AbstractQueue接口,如上圖的中Deque,LinkedList是一種雙端隊列的存儲方式
PriorityQueue 和 ConcurrentLinkedQueue(不阻塞隊列)
PriorityQueue 和 ConcurrentLinkedQueue 類在 Collection Framework 中加入兩個具體集合實現PriorityQueue 類實質上維護了一個有序列表。加入到 Queue 中的元素根據它們的天然排序(通過其 java.util.Comparable 實現)或者根據傳遞給構造函數的 java.util.Comparator 實現來定位。
ConcurrentLinkedQueue 是基于鏈接節點的、線程安全的隊列。并發訪問不需要同步。因為它在隊列的尾部添加元素并從頭部刪除它們,所以只要不需要知道隊列的大小,ConcurrentLinkedQueue 對公共集合的共享訪問就可以工作得很好。收集關于隊列大小的信息會很慢,需要遍歷隊列。
阻塞隊列
java.util.concurrent 中加入了 BlockingQueue 接口和五個阻塞隊列類。它實質上就是一種帶有一點扭曲的 FIFO 數據結構。不是立即從隊列中添加或者刪除元素,線程執行操作阻塞,直到有空間或者元素可用。
五個隊列所提供的各有不同:
* ArrayBlockingQueue :一個由數組支持的有界隊列。
* LinkedBlockingQueue :一個由鏈接節點支持的可選有界隊列。
* PriorityBlockingQueue :一個由優先級堆支持的無界優先級隊列。
* DelayQueue :一個由優先級堆支持的、基于時間的調度隊列。
* SynchronousQueue :一個利用 BlockingQueue 接口的簡單聚集(rendezvous)機制。