1. 程式人生 > >(八)數組以及排序和查找

(八)數組以及排序和查找

binary char and log 最簡 排序。 我認 最好 數組

JavaSE(八)

--數組以及排序和查找

一、數組的定義

三種定義方法:

int b[]=new int[5];

Int []b=new int[5];

int[] a=new int[5]; (建議使用這種定義方法) //必須規定數組長度,因為在編譯的時候就要分配內存。

我們也可以在定義的時候就初始化數組

Int[] a={1,2,3,3,5};

這默認了數組a的長度是5.

分配內存詳情如下:

開辟一塊內存,有5個小塊,a指向數組的首地址。

int[][] b=new int[5][]; //至少確定第一維的個數(即數組行數)才不會提示有錯。第二維的個數可以暫時不固定。

int[][][] b=new int[5][][]; 同理三維數組長度也至少確定第一維的個數才不會提示有錯。也可以確定一二維的個數,

int[][][] b=new int[5][4][]; 但是無法單跨維確定,例如int[][][] b=new int[5][][5];

二、數組的遍歷。

①只有確定了所有維數去遍歷一個數組才不會報錯。

②數組下標從0開始,到n-1結束(n為該維長度)。比如int[] s=new int[3]。這個數組長度為3s[0],s[1],s[2]就是這三個值,訪問s[3]是會報錯的,報數組越界異常java.lang.ArrayIndexOutOfBoundsException

為什麽是0開始呢?跟外國人建房子習慣有關,因為外國人建房子都會建地下室,地下室不就是0層了(地下一層也叫地上0層,因為在地上一層的下一層

)

③沒有初始化的時候,int數組所有元素值為0floatdouble所有元素值為0.0String所有元素值為nullChar所有元素都是一個空格(而不是什麽都沒有)

④ char[] c=new char[a]; //a為已知常數

遍歷方式一(for循環,用int變量控制)

for(int i=0;i<a;i++){

System.out.println(c[i]);

}

遍歷方式二(for循環)

for(char p:c){

System.out.println(p);

}

char[][] c=new char[a][b]; //a,b為已知常數

遍歷方式一(for循環,用

int變量控制)

for(int i=0;i<a;i++){

for(int j=0;j<b;j++){

System.out.println(c[i][j]);

}

}

遍歷方式二(for循環)

for(char i[]: c){

for(char j:i){

System.out.println(j);

}

}

三、排序

1.排序法種類:

內部排序: 指將需要處理的所有數據都加載到內部存儲器中進行排序。(包括交換式排序法、選擇式排序法、插入式排序法)

外部排序: 數據量過大,無法全部加載到內存中,需要借助外部存儲進行排序。(包括合並排序法和直接合並排序法)

交換式排序法,數據比較後,依判斷規則對數據位置進行交換,以達到排序的目的。

①冒泡排序法(Bubble sort)

②快速排序法(Quick sort)

選擇式排序法,是從欲排序的數據中,按指定的規則選出某一元素,經過和其他元素重整,再依原則交換位置後達到排序的目的。

①選擇排序法(Select sort)

②堆排序法(Heap Sort)

插入式排序法,是對欲排序的元素以插入的方式找尋該元素的適當位置,以達到排序的目的。

①插入排序法(Insertion sort)

②希爾排序法(Shell sort)

③二叉樹排序法(Binary-tree sort)

其它排序法。

①選堆排序法

②合並排序法

2.冒泡排序法

public static int[] bubble(int[] array){

int temp=0;

for(int i=0;i<array.length;i++){ //外層循環,決定一共走幾趟

for(int j=0;j<array.length-1-i;j++){ //內層循環,開始逐個比較,發現前一個數比後一個數大則交換

if(array[j]>array[j+1]){

temp=array[j];

array[j]=array[j+1];

array[j+1]=temp;

// array[j]=array[j]+array[j+1];

// array[j+1]=array[j]-array[j+1];

// array[j]=array[j]-array[j+1];

}

}

}

return array;

}

3.選擇排序法:

public static int[] select(int[] array){

int temp=0;

for(int j=0;j<array.length;j++){

//我認為第一個數就是最小的

int min=array[j];

//記錄最小數的下標

int minIndex=j;

for(int k=j+1;k<array.length;k++){

if(min>array[k]){

//修改最小

min=array[k];

minIndex=k;

}

}

temp=array[j];

array[j]=array[minIndex];

array[minIndex]=temp;

}

return array;

}

4.插入排序法:

public static int[] insert(int[] array){

for(int i=1;i<array.length;i++){

int insertVal=array[i];

//insertval準備和前一個數比較

int index=i-1;

while(index>=0&&insertVal<array[index]){

//array[index]向後移動

array[index+1]=array[index];

//index向前移動

index--;

}

//insertVal插入到適當位置

array[index+1]=insertVal;

}

return array;

}

5.快速排序法(交換式排序法):

public static int[] quick(int[] array){

int left=0;

int right=array.length-1;

return px(left, right, array);

}

public static int[] px(int left,int right,int[] array){

int l=left,r=right;

int privot=array[(l+r)/2];

int temp=0;

while(l<r){

while(array[l]<privot) l++;

while(array[r]>privot) r--;

if(l>=r) break;

temp=array[l];

array[l]=array[r];

array[r]=temp;

if(array[l]==privot) --r;

if(array[r]==privot) ++l;

}

if(l==r){

l++;

r--;

}

if(left<r) px(left,r,array);

if(right>l) px(l, right, array);

return array;

}

5.幾種排序方法運行時間的比較:

隨機生成十萬個1~10000的數並存放到數組中。

int[] array=new int[100000];

for(int i=0;i<array.length;i++){

array[i]=(int)(Math.random()*10000);

}

排序前打印系統時間,排序後打印系統時間。

Calendar calendar=Calendar.getInstance();

System.out.println("排序前:"+calendar.getTime());

bubble(array);

calendar=Calendar.getInstance();

System.out.println("排序後:"+calendar.getTime());

技術分享

發現排序時間大約是16

換成選擇排序法:

Calendar calendar=Calendar.getInstance();

System.out.println("排序前:"+calendar.getTime());

select(array);

calendar=Calendar.getInstance();

System.out.println("排序後:"+calendar.getTime());

技術分享

大約4秒鐘

換成插入排序法:

Calendar calendar=Calendar.getInstance();

System.out.println("排序前:"+calendar.getTime());

insert(array);

calendar=Calendar.getInstance();

System.out.println("排序後:"+calendar.getTime());

技術分享

大約3秒鐘

換成快速排序法:

Calendar calendar=Calendar.getInstance();

System.out.println("排序前:"+calendar.getTime());

quick(array);

calendar=Calendar.getInstance();

System.out.println("排序後:"+calendar.getTime());

技術分享

幾乎沒有排序時間。

6.淺測快速排序法

剛剛測試十萬個數發現幾乎沒有排序時間。

我又測試了一百萬個,發現還是沒什麽排序時間。

直到測試了一千萬個:

技術分享

發現僅有1s的排序時間。

那是不是快速排序法就是最好的呢?

不是,快速排序法在運行的時候對cpu和內存的占用是非常大的,其他排序法並不像快速排序法占用這麽多。

技術分享

技術分享

四、查找

java中我們常用的查找有兩種

①順序查找(最簡單,效率最低的查找方法,一個一個找)

②二分查找(先排序,再擇中查找,效率高)

public static void find(int val,int[] array){

int leftIndex=0;

int rightIndex=array.length-1;

f(leftIndex, rightIndex, val, array);

}

public static void f(int leftIndex,int rightIndex,int val,int array[]){

int midIndex=(rightIndex+leftIndex)/2;

int midVal=array[midIndex];

if(rightIndex>=leftIndex){

if(midVal>val){

f(leftIndex, midIndex-1, val, array);

}else if(midVal<val){

f(midIndex+1, rightIndex, val, array);

}else if(midVal==val){

System.out.println("找到此數,下標為"+midIndex);

}

}

}

二分查找要求數組已經是排好序(從小到大)的數組,所以我們一般先排序再使用二分查找。

(八)數組以及排序和查找