億級排序--垃圾筆記本78ms實現億級排序(下)
阿新 • • 發佈:2021-01-27
話不多說:先上成果引關注
tip:對於更大資料量,或者其他更嚴苛的環境,可考慮分治
測試結果
所耗時長
消耗記憶體: 極小(沒有開vmvare,用idea自帶的上升了4M)
電腦配置
需求
如何在1E級資料量中取出最大的100個數
思路:
採用自定義有序單鏈表過濾(這裡是升序)
- 對於比最左值小的值,直接捨棄,不做任何處理
- 對於比最右(最大值)大的值,連結串列右移(即刪除最左邊,新增最右邊)
- 對於比最左值大,比最大值小,下標右移,直至遇到比他大的值,
- 對於只比最左值大,最左直接改值
- 對於中間值(比最左邊大,比最右值小的值),我們把最左結點賦予該值,並抽出插入中間(位置在2已獲取)
對於更大數量級的資料量,我們可以採用分治思想,所以該思路理論上可以處理無限數量級資料
package practice;
import java.util.*;
public class Main {
class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
}
public ListNode createNode (int val){
return new ListNode(val);
}
public static void main(String[] args) {
Main main = new Main();
int ti=0;
//賦予1E個隨機數字,用於排序
int[] arr=new int[10000*10000];
Random random=new Random();
for (int i = 0; i < arr.length; i++) {
arr[ i]=random.nextInt();
}
//開始計時
long start = System.currentTimeMillis();
//抽取陣列前100位並排序,用於初始化連結串列
int[] ints = Arrays.copyOfRange(arr, 0, 100);
Arrays.sort(ints);
ListNode root=main.createNode(0);
root.next=main.createNode(Integer.MIN_VALUE);
ListNode curr=root.next;
//記錄最後一個
ListNode last=curr;
//初始化長度100的連結串列
for (int i = 0; i < ints.length; i++) {
curr.next=main.createNode(ints[i]);
last=curr;
curr=curr.next;
}
//篩除最大100個
for (int i = 0; i < arr.length; i++) {
curr=root.next;
//比最左大才判斷,否則直接捨棄
if (arr[i]>curr.val) {
//首先跟最右比較,比最右大
if (arr[i] >= last.val) {
//是最大,刪除最左,新增最右
root.next = root.next.next;
last.next = main.createNode(arr[i]);
last = last.next;
} else {
//比最左邊大,下標右移,直至右邊比其大
while (curr.next != null && arr[i] > curr.next.val) {
curr = curr.next;
}
//右移完成
//處於最左邊,最左邊直接複製
if (curr.val==root.next.val) {
curr.val=arr[i];
}
//處於中間
else {
//增加新中間節點,廢物利用,減少新物件的建立
ListNode node=root.next;
node.val=arr[i];
//刪除最左節點
root.next = root.next.next;
//串聯新增節點
node.next=curr.next;
curr.next=node;
}
}
}
}
//計時結束
System.out.println("總計用時");
System.out.println(System.currentTimeMillis()-start);
//遍歷,校驗結果
curr=root.next;
while (curr!=null)
{
System.out.println(curr.val);
curr=curr.next;
}
}
}