日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java基数排序 数组_万字长文带你掌握Java数组与排序,代码实现原理都帮你搞明白!...

發布時間:2024/9/27 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java基数排序 数组_万字长文带你掌握Java数组与排序,代码实现原理都帮你搞明白!... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

查找元素索引位置

基本查找

根據數組元素找出該元素第一次在數組中出現的索引

public class TestArray1 {

public static void main(String[] args) {

//定義一個數組

int[] arr={10,20,70,10,90,100,1,2};

//根據元素查找出該元素在數組中第一次出現的索引

int index=getIndexByEle(arr,2);

System.out.println("該元素第一次在數組中出現的索引是:"+index);

}

private static int getIndexByEle(int[] arr, int ele) {

//遍歷數組,去查找

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

if (ele==arr[i]){

return i;

}

}

return -1;//如果我們沒有找到這個元素那么就返回-1

}

}

案例中查找元素2的索引,索引為7;

運行后返回結果正確:

二分查找

使用二分查找查找出該元素在數組中第一次出現的索引

前提:該數組的元素必須有序

思想:每一次都查找中間的元素,比較大小就能減少一半的元素

具體代碼實現:

public class TestArray2 {

public static void main(String[] args) {

//二分查找:前提是數組元素必須有序

int[] arr={10,20,30,40,50,60,70,80,90};

int index=getIndexByEle(arr,40);

System.out.println("該元素的索引是:"+index);

}

private static int getIndexByEle(int[] arr, int ele) {

//定義最小索引,中間索引,最大索引

int minIndex=0;

int maxIndex=arr.length-1;

int centerIndex=(minIndex+maxIndex)/2;

while (minIndex<=maxIndex){

//如果需查找元素等于中間索引所對應元素,返回中間元素,表示找到

if (ele==arr[centerIndex]){

return centerIndex;

}

//如果需查找元素大于中間索引所對應元素,移動最小索引至中間索引處

else if (ele>arr[centerIndex]){

minIndex=centerIndex+1;

}

//如果需查找元素小于中間索引所對應元素,移動最大索引至中間索引處

else if (ele

maxIndex=centerIndex-1;

}

//重新計算中間索索引

centerIndex=(minIndex+maxIndex)/2;

}

return -1;//如果沒有找到,就返回-1

}

}

案例中查找元素為40,索引為3;

運行后返回結果正確:

八大排序方法

冒泡排序

原理:數組元素兩兩比較,交換位置,大元素往后放,經過一輪比較后,最大的元素,就會被排到數組的最后

圖解:

代碼部分:

先進行第一輪排序,看看效果:

public class ArraySort1 {

public static void main(String[] args) {

//原理:數組元素兩兩比較,前面元素大于后面元素則交換,否則不交換,每經過一輪,最大的元素會排到最后

int[] arr={24,69,80,57,13};

//第一輪比較,遍歷數組

for (int i = 0; i < arr.length-1; i++) {

//從從第0個元素開始,前一個元素與后一個元素比較

if (arr[i]>arr[i+1]){

//滿足條件則交換位置,利用temp中間變量寄存元素

int temp=arr[i];

arr[i]=arr[i+1];

arr[i+1]=temp;

}

}

//輸出數組

System.out.println(Arrays.toString(arr));

}

}

下面進行多輪排序:

代碼部分

笨方法:多次for循環,比較繁瑣,重復循環,語句沒營養,看看就好,主要是得能想到,為嵌套循環做準備

public class ArraySort1 {

public static void main(String[] args) {

//原理:數組元素兩兩比較,前面元素大于后面元素則交換,否則不交換,每經過一輪,最大的元素會排到最后

int[] arr={24,69,80,57,13};

//第一輪比較,遍歷數組

for (int i = 0; i < arr.length-1; i++) {

//從從第0個元素開始,前一個元素與后一個元素比較

if (arr[i]>arr[i+1]){

//滿足條件則交換位置,利用temp中間變量寄存元素

int temp=arr[i];

arr[i]=arr[i+1];

arr[i+1]=temp;

}

}

//輸出數組

System.out.println(Arrays.toString(arr));

//第二輪比較,遍歷數組

for (int i = 0; i < arr.length-1-1; i++) {

if (arr[i]>arr[i+1]){

int temp=arr[i];

arr[i]=arr[i+1];

arr[i+1]=temp;

}

}

//輸出數組

System.out.println(Arrays.toString(arr));

//第三輪比較,遍歷數組

for (int i = 0; i < arr.length-1-1-1; i++) {

if (arr[i]>arr[i+1]){

int temp=arr[i];

arr[i]=arr[i+1];

arr[i+1]=temp;

}

}

//輸出數組

System.out.println(Arrays.toString(arr));

//第四輪比較,遍歷數組

for (int i = 0; i < arr.length-1-1-1-1; i++) {

if (arr[i]>arr[i+1]){

int temp=arr[i];

arr[i]=arr[i+1];

arr[i+1]=temp;

}

}

//輸出數組

System.out.println(Arrays.toString(arr));

}

}

使用嵌套循環(語句精簡,沒有廢話):

public class ArraySort1 {

public static void main(String[] args) {

//原理:數組元素兩兩比較,前面元素大于后面元素則交換,否則不交換,每經過一輪,最大的元素會排到最后

int[] arr={24,69,80,57,13};

//嵌套for循環,外層循環輪數,內層對每一輪內元素進行比較

for (int i = 0; i < arr.length - 1; i++) {

for (int j = 0; j < arr.length-1-i; j++) {

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

//交換位置

int temp=arr[j];

arr[j]=arr[j+1];

arr[j+1]=temp;

}

}

}

System.out.println(Arrays.toString(arr));

}

冒泡排序就介紹到這里~~~

選擇排序

原理:從0索引處開始,依次和后面的元素進行比較,小的元素往前放,經過一輪比較后,最小的元素就會出現在最小索引處

圖解:

代碼部分:多輪排序(優化前)

public class ArraySort2 {

public static void main(String[] args) {

//原理:從0索引處開始,依次個后面的元素進行比較,小的元素往前放,經過一輪比較,最小的元素就出現在最小索引處

int[] arr={24,69,80,57,13};

//第一輪比較,從0索引處開始比

int index=0;

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

if (arr[index]>arr[i]){

int temp=arr[index];

arr[index]=arr[i];

arr[i]=temp;

}

}

System.out.println(Arrays.toString(arr));

//第二輪

index=1;

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

if (arr[index]>arr[i]){

int temp=arr[index];

arr[index]=arr[i];

arr[i]=temp;

}

}

System.out.println(Arrays.toString(arr));

//第三輪

index=2;

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

if (arr[index]>arr[i]){

int temp=arr[index];

arr[index]=arr[i];

arr[i]=temp;

}

}

System.out.println(Arrays.toString(arr));

//第四輪

index=3;

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

if (arr[index]>arr[i]){

int temp=arr[index];

arr[index]=arr[i];

arr[i]=temp;

}

}

System.out.println(Arrays.toString(arr));

}

}

優化代碼:嵌套循環:

public class ArraySort2 {

public static void main(String[] args) {

//原理:從0索引處開始,依次個后面的元素進行比較,小的元素往前放,經過一輪比較,最小的元素就出現在最小索引處

int[] arr={24,69,80,57,13};

//第一輪比較,從0索引處開始比

for (int index = 0; index < arr.length-1; index++) {

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

if (arr[index]>arr[i]){

int temp=arr[index];

arr[index]=arr[i];

arr[i]=temp;

}

}

}

System.out.println(Arrays.toString(arr));

}

選擇排序就介紹到這里~~~

直接插入排序

原理:從1索引處開始,將后面的元素與前一位比,小于前一位則交換,再與前一位比,如果小于再交換,如此循環,插入之前的有序列表中使之仍保持有序

(方法1):代碼實現:

public class ArraySort3 {

public static void main(String[] args) {

//直接插入排序:從1索引處開始,將后面的元素,插入之前的有序列表中使之仍保持有序

int[] arr={3,2,1,0,10,20,30,7,8};

//外層循環定義輪次

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

//內層循環進行比較插入

int j=i;

while (j>0 && arr[j]

int temp=arr[j];

arr[j]=arr[j-1];

arr[j-1]=temp;

j--;

}

}

System.out.println(Arrays.toString(arr));

}

}

(方法2)代碼實現:

public class ArraySort3 {

public static void main(String[] args) {

//直接插入排序:從1索引處開始,將后面的元素,插入之前的有序列表中使之仍保持有序

int[] arr={3,2,1,0,10,20,30,7,8};

//外層循環定義輪次

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

for (int j = i; j >0 ; j--) {

if (arr[j]

int temp=arr[j];

arr[j]=arr[j-1];

arr[j-1]=temp;

}

}

}

System.out.println(Arrays.toString(arr));

}

由于很多地方需要使用前后元素值交換,因此封裝成一個方法:代碼如下:

public static void swapValue(int[] arr,int i,int j){

int temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

使用自己封裝的方法:

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

for (int j = i; j >0 ; j--) {

if (arr[j]

/*

int temp=arr[j];

arr[j]=arr[j-1];

arr[j-1]=temp;

*/

//直接調用交換方法,封裝思想

swapValue(arr,j,j-1);

}

}

}

直接插入排序就介紹到這里~~~

希爾排序

希爾排序又稱縮小增量排序

基本思想:先將原表按增量ht分組;每個子文件按照直接插入法排序。同樣,用下一個增量ht/2將文件再分為自問見,在直接插入法排序。直到ht=1時整個文件排好序。

關鍵:選擇合適的增量。

希爾排序算法9-3:可以通過三重循環來實現。

圖示:

將數組按步長為5的間隔兩兩分為一組,每組兩個元素進行比較大小,小的放置于前面,大的放置于后面;

由此排序一次后,大致可以將整個數組中較小的元素放在前面,較大的放在后面。

下面數組長度為8,第一次間隔取4,第二次間隔取2,第三次間隔取1,具體實現見下圖:

代碼實現(使用克努特序列,合理選擇增量):

public class ArraySort4 {

public static void main(String[] args) {

//希爾排序,對插入排序的優化,核心思想就是合理的選取增量,經過一輪排序后,就會讓序列大致有序

//然后不斷的縮小增量,進行插入排序,直到增量為1整個排序結束

//直接插入排序,其實就是增量為1的希爾排序

int[] arr={46,55,13,43,17,94,5,70,11,25,110,234,1,3,66};

shellSort(arr);

System.out.println(Arrays.toString(arr));

}

private static void shellSort(int[] arr) {

//定義一個增量

/*

//第一輪

int h=4;

for (int i = h; i < arr.length; i++) {

for (int j = i; j > h-1 ; j-=h) {

if (arr[j]

swapValue(arr,j,j-h);

}

}

}

//第二輪

h=2;

for (int i = h; i < arr.length; i++) {

for (int j = i; j > h-1 ; j-=h) {

if (arr[j]

swapValue(arr,j,j-h);

}

}

}

//第三輪

h=1;

for (int i = h; i < arr.length; i++) {

for (int j = i; j > h-1 ; j-=h) {

if (arr[j]

swapValue(arr,j,j-h);

}

}

}

*/

//希爾排序核心代碼

//希爾排序的思想,合理的選取增量

//第一次增量可以選取數組長度的一半,然后不斷的減半

/*for (int h = arr.length / 2; h > 0; h /= 2) {

for (int i = h; i < arr.length; i++) {

for (int j = i; j > h - 1; j -= h) {

if (arr[j] < arr[j - h]) {

swapValue(arr, j, j - h);

}

}

}

}*/

//增量的選取選擇數組長度的一半,還不是很合理,我們可以使用一種序列,叫做克努特序列

//int h = 1;

//h = h * 3 + 1; //1,4,13,40,121,364

//根據克努特序列選取我們的第一次增量

int jiange = 1;

while (jiange <= arr.length / 3) {

jiange = jiange * 3 + 1;

}

for (int h = jiange; h > 0; h = (h - 1) / 3) {

for (int i = h; i < arr.length; i++) {

for (int j = i; j > h - 1; j -= h) {

if (arr[j] < arr[j - h]) {

swapValue(arr, j, j - h);

}

}

}

}

}

//封裝元素交換方法

public static void swapValue(int[] arr,int i,int j){

int temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

}

希爾排序就介紹到這里~~~

快速排序

原理:分治法:比大小,再分區

從數組中取出一個數,作為基準數

分區:將比這個數大或等于的書全放到他的右邊,小于他的數全放到他的左邊。

再對左右區間重復第二步,直到各區間只有一個數。

實現思路

將基準數挖出形成第一個坑

由后向前找比它小的數,找到后挖出此數填到前一個坑中

由前向后找比它大或等于的數,找到后也挖出此數填到前一個坑中。

再重復執行上述兩步驟

代碼實現:

public class ArraySort5 {

public static void main(String[] args) {

//定義一個數組

int[] arr={10,3,34,45,11,35,255,4,-1,-9,79,123};

quickSort(arr,0,arr.length-1);

System.out.println(Arrays.toString(arr));

}

//快速排序

public static void quickSort(int[] arr,int start,int end) {

//找出分左右兩區的索引位置,然后對左右兩區進行遞歸調用

if (start

int index=getIndex(arr,start,end);

quickSort(arr,start,index-1);

quickSort(arr,index+1,end);

}

}

//將基準數挖出形成第一個坑

//由后向前找比它小的數,找到后挖出此數填到前一個坑中

//由前向后找比它大或等于的數,找到后也挖出此數填到前一個坑中。

//再重復執行上述兩步驟

private static int getIndex(int[] arr, int start, int end) {

int i=start;

int j=end;

int x=arr[i];

while (i

//由后向前找比它小的數,找到后挖出此數填到前一個坑中

while (i=x){

j--;

}

if (i

arr[i]=arr[j];

i++;

}

//由前向后找比它大或等于的數,找到后也挖出此數填到前一個坑中。

while (i

i++;

}

if (i

arr[j]=arr[i];

j--;

}

}

arr[i]=x;//把基準數填到最后一個坑

return i;

}

}

快速排序就介紹到這里~~~

歸并排序

歸并排序(Merge Sort)就是利用歸并的思想實現排序的方法

原理:假設初始序列有N個記錄,則可以看成是N個有序的子序列,每個子序列的長度為1,然后兩兩歸并,得到N/2個長度為2或1的有序子序列,再兩兩歸并。。。如此重復,直至得到一個長度為N的有序序列為止,這種排序方法稱為2路歸并排序

代碼實現:

public class ArraySort6 {

public static void main(String[] args) {

//原始待排序數組

int[] arr={10,23,1,43,0,-3,1121,343,44,11,56,78,3,-1};

//我們先給一個左右兩邊是有序的一個數組,先來進行歸并操作

//int[] arr={4,5,7,8,1,2,3,6};

//拆分

chaifen(arr,0,arr.length-1);

//歸并

guiBing(arr,0,3,arr.length-1);

//輸出原數組

System.out.println(Arrays.toString(arr));

}

private static void chaifen(int[] arr, int startIndex, int endIndex) {

//計算中間索引

int centerIndex=(startIndex+endIndex)/2;

if (startIndex

chaifen(arr,startIndex,centerIndex);

chaifen(arr,centerIndex+1,endIndex);

guiBing(arr,startIndex,centerIndex,endIndex);

}

}

private static void guiBing(int[] arr, int startIndex, int centerIndex, int enIndex) {

//定義一個臨時數組

int[] tempArr=new int[enIndex-startIndex+1];

//定義左邊數組的起始索引

int i=startIndex;

//定義右邊數組的起始索引

int j=centerIndex+1;

//定義臨時數組的起始索引

int index=0;

while (i<=centerIndex && j<=enIndex){

if (arr[i]<=arr[j]){

tempArr[index]=arr[i];

i++;

}else{

tempArr[index]=arr[j];

j++;

}

index++;

}

//處理剩余元素

while (i<=centerIndex){

tempArr[index]=arr[i];

i++;

index++;

}

while (j<=enIndex){

tempArr[index]=arr[j];

j++;

index++;

}

//將臨時數組中的元素取到原數組中

for (int k = 0; k < tempArr.length; k++) {

arr[k+startIndex]=tempArr[k];

}

}

}

歸并排序就介紹到這里~~~

基數排序

基數排序不同于之前的各類排序

前面的排序或多或少通過使用比較和移動記錄來實現排序

而基數排序的實現不需要進行對關鍵字的比較,只需要對關鍵字進行“分配”與“收集”兩種操作即可完成

下面通過圖來解釋:

第一次排序:按照個位進行分組

分組后結果:

再將元素逐一取出:

第二次排序:根據十位上的數進行排序

再依次將元素取出:

第三輪排序:根據百位上的數進行排序

最后將所有元素取出:

代碼實現:

public class ArraySort7 {

public static void main(String[] args) {

//基數排序:通過分配再收集的方式進行排序

int[] arr={2,0,1,5,21,31,224,355,22,41,67,23,444,789,12,55,34,75};

//確定排序輪次

//獲取數組中的最大值

int max=getMax(arr);

//基數排序

sortArray(arr);

//輸出排序后的數組

System.out.println(Arrays.toString(arr));

}

private static void sortArray(int[] arr) {

//定義二維數組,放10個桶

int[][] tempArr=new int[10][arr.length];

//定義統計數組

int[] counts=new int[10];

int max=getMax(arr);

int len=String.valueOf(max).length();

//循環輪次

for (int i = 0,n=1; i < len; i++,n*=10) {

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

//獲取每個位上的數字

int ys=arr[j]/n%10;

tempArr[ys][counts[ys]++]=arr[j];

}

//取出桶中的元素

int index=0;

for (int k = 0; k < counts.length; k++) {

if (counts[k]!=0){

for (int h = 0; h < counts[k]; h++) {

//從桶中取出元素放回原數組

arr[index]=tempArr[k][h];

index++;

}

counts[k]=0;//清除上一次統計的個數

}

}

}

}

private static int getMax(int[] arr) {

int max=arr[0];

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

if (arr[i]>max){

max=arr[i];

}

}

return max;

}

}

基數排序就介紹到這里~~~

堆排序

堆排序是利用堆這種數據結構而設計的一種排序算法,堆排序是一種選擇排序

將待排序序列構造成一個大頂堆,此時,整個序列的最大值就是堆頂的根節點。

將其與末尾元素進行交換,此時末尾就為最大值

然后將剩余n-1個元素重新構造成一個堆,這樣就會得到n個元素的次小值

如此反復的執行,便能得到一個有序序列了

代碼實現:

public class ArraySort8 {

public static void main(String[] args) {

//定義一個數組

int[] arr={1,0,6,7,2,3,4,5,8,9,10,52,12,33};

//調整成大頂堆的方法

//定義開始調整的位置

int startIndex=(arr.length-1)/2;

//循環開始調

for (int i = startIndex; i >=0 ; i--) {

toMaxHeap(arr,arr.length,i);

}

//System.out.println(Arrays.toString(arr));

//經過上面的操作后,已經把數組變成一個大頂堆,把根元素和最后一個元素進行調換

for (int i = arr.length-1; i >0; i--) {

//進行調換

int temp=arr[0];

arr[0]=arr[i];

arr[i]=temp;

//換完之后,我們再把剩余元素調成大頂堆

toMaxHeap(arr,i,0);

}

System.out.println(Arrays.toString(arr));

}

/**

*

* @param arr 要排序的數組

* @param size 調整的元素個數

* @param index 從哪里開始調整

*/

private static void toMaxHeap(int[] arr, int size, int index) {

//獲取左右字節的索引

int leftNodeIndex=index*2+1;

int rightNodeIndex=index*2+2;

//查找最大節點所對應的索引

int maxIndex=index;

if (leftNodeIndexarr[maxIndex]){

maxIndex=leftNodeIndex;

}

if(rightNodeIndexarr[maxIndex]){

maxIndex=rightNodeIndex;

}

//我們來調換位置

if(maxIndex!=index){

int t=arr[maxIndex];

arr[maxIndex]=arr[index];

arr[index]=t;

//調換完之后,可能會影響到下面的子樹,不是大頂堆,我們還需要再次調換

toMaxHeap(arr,size,maxIndex);

}

}

}

堆排序就介紹到這里~~~

最后

感謝你看到這里,文章有什么不足還請指正,覺得文章對你有幫助的話記得給我點個贊,每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的java基数排序 数组_万字长文带你掌握Java数组与排序,代码实现原理都帮你搞明白!...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。