欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報(bào)激活碼778899分享:JAVA 詳解常見排序

柚子快報(bào)激活碼778899分享:JAVA 詳解常見排序

http://yzkb.51969.com/

目錄

?編輯

插入排序

希爾排序(縮小增量排序)

選擇排序

冒泡排序

堆排序

快速排序

hoare版

?挖坑法

前后指針法

非遞歸版

歸并排序

遞歸版

非遞歸版

計(jì)數(shù)排序

聲明:以下排序代碼由Java實(shí)現(xiàn)!!!

插入排序

步驟:

1.我們可以認(rèn)為數(shù)組的第一個元素已經(jīng)被排好序,因此只需考慮對后面的元素進(jìn)行插入排序;

2.取下一個位置的元素val,讓它和它之前的元素進(jìn)行比較,順序?yàn)閺挠蚁蜃螅?/p>

3.如果該元素大于val,則將該元素移動到該元素所處位置的下一個位置;

4.重復(fù)步驟3,知道找到已排好序的序列中小于等于val的元素;

5.將值val放到該位置的下一個位置,如果已排好序的所有元素的值都大于val,則將val存放到數(shù)組下標(biāo)為0的位置;

6.重復(fù)2~5步驟。

動畫演示:

代碼如下:

public static void insertSort(int[] array){

for(int i=1;i

int tmp=array[i];

int j=i-1;

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

if(array[j]>tmp)

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

else

break;

}

array[j+1]=tmp;

}

}

折半插入排序?

在該值為val的元素找合適的位置時,是在已排好序的序列中進(jìn)行找的,因此該過程可以使用二分查找(折半查找)來進(jìn)行優(yōu)化。

代碼如下:

public static void bsInsertSort(int[] array){

for(int i=0;i

int tmp=array[i];

int left=0,right=i;

while(left

int mid=(left+right)>>1;

if(tmp>=array[mid])

left=mid+1;

else

right=mid;

}

for(int j=i;j>left;j--)

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

array[left]=tmp;

}

}

時間復(fù)雜度:最好情況下為O(N),此時待排數(shù)組為升序,或者說非常接近升序;

? ? ? ? ? ? ? ? ? ? ?最壞情況下為O(N^N),此時待排數(shù)組為降序,或者說非常接近降序。

空間復(fù)雜度:O(1)

穩(wěn)定性:穩(wěn)定

希爾排序(縮小增量排序)

思想:

先選定一個小于N的整數(shù)gap作為第一增量,然后將所有距離為gap的元素劃分在同一組,對每組的元素進(jìn)行直接插入排序,然后再選取一個比第一增量小的整數(shù)作為第二增量gap,然后將所有距離為gap的元素劃分在同一組,對每組的元素進(jìn)行直接插入排序,以此類推.........,直到增量減小為1時,此時就相當(dāng)于整個數(shù)組被劃分為一組,進(jìn)行一次直接插入排序即可。

增量gap大于1時,稱為“預(yù)排序”,使得待排數(shù)組接近有序;增量gap為1時,稱為直接插入排序。

動畫演示

代碼如下:

public static void shellSort(int[] array){

int gap=array.length;

while(gap>1){

gap=gap/3+1;

shell(array,gap);

}

}

private static void shell(int[] array,int gap){

for(int i=gap;i

int tmp=array[i];

int j=i-gap;

for(;j>=0;j-=gap){

if(array[j]>tmp)

array[j+gap]=array[j];

else

break;

}

array[j+gap]=tmp;

}

}

平均時間復(fù)雜度:O(N^1.3)

空間復(fù)雜度:O(1)

選擇排序

每一次從待排序列中選出最?。ɑ蛘咦畲螅┑囊粋€元素,存放在待排序列的起始位置,同時將待排序列原來起始位置的值放到待排序列中最小元素的位置,直到待排數(shù)據(jù)全部排完序。

動畫演示

代碼如下:

public static void selectSort(int[] array){

for(int i=0;i

int minIndex=i;

for(int j=i+1;j

if(array[j]

minIndex=j;

swap(array,i,minIndex);

}

}

private static void swap(int[] array,int i,int j){

int ret=array[i];

array[i]=array[j];

array[j]=ret;

}

實(shí)際上,我們可以每一趟同時選擇出待排序列中的最小值和最大值,然后將最小值放待排序列起始位置,將最大值放到待排序列的末尾,直到待排數(shù)據(jù)全部排完序,這樣的話比前一種方法快一倍。

代碼如下:

public static void DoubleSelectSort(int[] array){

int left=0,right=array.length-1;

while(left

int minIndex=left,maxIndex=left;

for(int i=left+1;i<=right;i++){

if(array[i]>array[maxIndex])

maxIndex=i;

if(array[i]

minIndex=i;

}

swap(array,left,minIndex);

if(maxIndex==left)

maxIndex=minIndex;

swap(array,right,maxIndex);

left++;

right--;

}

}

private static void swap(int[] array,int i,int j){

int ret=array[i];

array[i]=array[j];

array[j]=ret;

}

時間復(fù)雜度:O(N^2)

空間復(fù)雜度:O(1)

冒泡排序

進(jìn)行N趟,每一趟中,如果前一個位置的元素大于后一個位置的元素,則交換兩個位置的元素。

動畫演示

代碼如下:

public static void bubbleSort(int[] array){

for(int i=0;i

boolean flag=false;

for(int j=0;j

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

swap(array, j, j + 1);

flag=true;

}

}

if(!flag)

break;

}

}

時間復(fù)雜度:O(N^2)

空間復(fù)雜度:O(1)

堆排序

排升序建大根堆,排降序建小根堆。

以排升序?yàn)槔?,先對?shù)組建立大根堆,然后將堆頂元素和堆最后一個元素交換,然后從堆頂進(jìn)行向下調(diào)整,不過此時堆的大小要 -1,因?yàn)橐呀?jīng)把最大的元素找出來并放在數(shù)組的末尾了,不斷重復(fù)上述操作,直到將整個數(shù)組的元素排完序。

動畫演示:

代碼如下:

public static void heapSort(int[] array){

createBigHeap(array);

int end=array.length-1;

while(end>0){

swap(array,0,end);

shiftDown(array,0,end);

end--;

}

}

private static void createBigHeap(int[] array){

for(int parent=array.length-1-1;parent>=0;parent--)

shiftDown(array,parent,array.length);

}

private static void shiftDown(int[] array,int parent,int end){

int child=2*parent+1;

while(child

if(child+1array[child])

child++;

if(array[parent]

swap(array,parent,child);

parent=child;

child=2*parent+1;

}

else

break;

}

}

private static void swap(int[] array,int i,int j){

int ret=array[i];

array[i]=array[j];

array[j]=ret;

}

時間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(1)

快速排序

hoare版

步驟:

1.選定一個值Key,下標(biāo)記為Keyi,通常是最左邊的元素或者最右邊的元素;

2.定義兩個指針begin和end,being從左往右走,end從右往左走;

3.若選定的Key值是最左邊的元素,需要end先走,若選定的Key值是最右邊的元素,需要begin先走;

4.在走的過程中,當(dāng)end遇到小于Key的數(shù),才停下;然后begin開始走,直到遇到大于Key的數(shù),然后交換位于begin和end位置的值,然后end再走,規(guī)則如上,直到begin和end相遇,此時再將位于Keyi位置的Key值和begin和end相遇點(diǎn)的值進(jìn)行交換;

5.此時,Key左邊的值都是小于等于Key的數(shù),Key右邊的值都是大于等于Key的數(shù);

6.然后再對Key左邊的數(shù)以及Key右邊的數(shù)分別進(jìn)行如上操作,直到待排序列只有一個元素為止。

動畫演示:

代碼如下:?

因?yàn)樵摲椒ò罅康倪f歸,當(dāng)數(shù)據(jù)量較大時會發(fā)生棧溢出,因此做一些優(yōu)化,包括【三數(shù)取中】和【當(dāng)待排區(qū)間長度小于某個常數(shù)時,不再遞歸進(jìn)行快排,而是使用直接插入排序】

public static void quickSort(int[] array){

quick(array,0,array.length-1);

}

private static void quick(int[] array,int start,int end){

if(start>=end) return;

if(end-start<=7){

insertSortRange(array,start,end);

return;

}

int pivot=partitionHoare(array,start,end);

quick(array,start,pivot-1);

quick(array,pivot+1,end);

}

private static void insertSortRange(int[] array,int begin,int end) {

for (int i = begin+1; i <= end; i++) {

int tmp = array[i];

int j = i-1;

for (; j >= begin ; j--) {

if(array[j] > tmp) {

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

}else {

break;

}

}

array[j+1] = tmp;

}

}

private static int midOfThree(int[] array, int left, int right) {

int mid = (left+right) / 2;

if(array[left] < array[right]) {

if(array[mid] < array[left]) {

return left;

}else if(array[mid] > array[right]) {

return right;

}else {

return mid;

}

}else {

if(array[mid] > array[left]) {

return left;

}else if(array[mid] < array[right]) {

return right;

}else {

return mid;

}

}

}

private static int partitionHoare(int[] array,int left,int right){

int key=array[left];

int keyi=left;

while(left

while(left=key)

right--;

while(left

left++;

swap(array,left,right);

}

swap(array,keyi,left);

return left;

}

private static void swap(int[] array,int i,int j){

int ret=array[i];

array[i]=array[j];

array[j]=ret;

}

時間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(1)?

?挖坑法

步驟:

1.選定一個Key值,通常是位于最左邊或者是最右邊,在該位置形成一個坑;

2.定義兩個指針left和right,left從左向右走,right從左向左走;

3.如果Key值位于數(shù)組最左邊,需要right先走;如果Key值位于數(shù)組組右邊,需要left先走;

4.在走的過程中,當(dāng)end遇到小于Key的數(shù),才停下,然后將right位置的值填放到坑位置,此時right位置處形成一個坑;然后begin開始走,直到遇到大于Key的數(shù),然后將left位置的值填放到坑位置,此時left位置處形成一個坑;然后right再走,規(guī)則如上,直到left和right相遇,此時再將位于Key值填放到坑位置處;

5.此時,Key左邊的值都是小于等于Key的數(shù),Key右邊的值都是大于等于Key的數(shù);

6.然后再對Key左邊的數(shù)以及Key右邊的數(shù)分別進(jìn)行如上操作,直到待排序列只有一個元素為止。

動畫演示:

代碼如下:?

因?yàn)樵摲椒ò罅康倪f歸,當(dāng)數(shù)據(jù)量較大時會發(fā)生棧溢出,因此做一些優(yōu)化,包括【三數(shù)取中】和【當(dāng)待排區(qū)間長度小于某個常數(shù)時,不再遞歸進(jìn)行快排,而是使用直接插入排序】

public static void quickSort(int[] array){

quick(array,0,array.length-1);

}

private static void quick(int[] array,int start,int end){

if(start>=end) return;

if(end-start<=7){

insertSortRange(array,start,end);

return;

}

int pivot=partitionHole(array,start,end);

quick(array,start,pivot-1);

quick(array,pivot+1,end);

}

private static void insertSortRange(int[] array,int begin,int end) {

for (int i = begin+1; i <= end; i++) {

int tmp = array[i];

int j = i-1;

for (; j >= begin ; j--) {

if(array[j] > tmp) {

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

}else {

break;

}

}

array[j+1] = tmp;

}

}

private static int midOfThree(int[] array, int left, int right) {

int mid = (left+right) / 2;

if(array[left] < array[right]) {

if(array[mid] < array[left]) {

return left;

}else if(array[mid] > array[right]) {

return right;

}else {

return mid;

}

}else {

if(array[mid] > array[left]) {

return left;

}else if(array[mid] < array[right]) {

return right;

}else {

return mid;

}

}

}

private static int partitionHole(int[] array,int left,int right){

int key=array[left];

while(left

while(left=key)

right--;

array[left]=array[right];

while(left

left++;

array[right]=array[left];

}

array[left]=key;

return left;

}

private static void swap(int[] array,int i,int j){

int ret=array[i];

array[i]=array[j];

array[j]=ret;

}

時間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(1)?

前后指針法

步驟:

1.選定數(shù)組最左邊的值為基準(zhǔn)值;

2.定義兩個指針prev和cur,開始時prev在最左邊,cur在prev的下一個位置;

3.讓cur向右走,如果cur位置的值大于基準(zhǔn)值,只需cur繼續(xù)向右移動,直到遇到比基準(zhǔn)值小的值;

4.如果cur位置的值小于基準(zhǔn)值,先讓prev向右移動一個位置,然后交換prev位置的值和cur位置的值,直到cur走到數(shù)組末尾。

代碼如下:

因?yàn)樵摲椒ò罅康倪f歸,當(dāng)數(shù)據(jù)量較大時會發(fā)生棧溢出,因此做一些優(yōu)化,包括【三數(shù)取中】和【當(dāng)待排區(qū)間長度小于某個常數(shù)時,不再遞歸進(jìn)行快排,而是使用直接插入排序】

public static void quickSort(int[] array){

quick(array,0,array.length-1);

}

private static void quick(int[] array,int start,int end){

if(start>=end) return;

if(end-start<=7){

insertSortRange(array,start,end);

return;

}

int pivot=partitionDouble(array,start,end);

quick(array,start,pivot-1);

quick(array,pivot+1,end);

}

private static void insertSortRange(int[] array,int begin,int end) {

for (int i = begin+1; i <= end; i++) {

int tmp = array[i];

int j = i-1;

for (; j >= begin ; j--) {

if(array[j] > tmp) {

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

}else {

break;

}

}

array[j+1] = tmp;

}

}

private static int midOfThree(int[] array, int left, int right) {

int mid = (left+right) / 2;

if(array[left] < array[right]) {

if(array[mid] < array[left]) {

return left;

}else if(array[mid] > array[right]) {

return right;

}else {

return mid;

}

}else {

if(array[mid] > array[left]) {

return left;

}else if(array[mid] < array[right]) {

return right;

}else {

return mid;

}

}

}

private static int partitionDouble(int[] array,int left,int right){

int prev=left,cur=prev+1;

while(cur

if(array[cur]

swap(array,prev,cur);

cur++;

}

swap(array,prev,left);

return prev;

}

private static void swap(int[] array,int i,int j){

int ret=array[i];

array[i]=array[j];

array[j]=ret;

}

時間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(1)?

非遞歸版

代碼如下:

public static void quickSortNor(int[] array) {

Stack stack = new Stack<>();

int left = 0;

int right = array.length-1;

int piovt = partitionHole(array,left,right);

if(piovt - 1 > left) {

stack.push(left);

stack.push(piovt-1);

}

if(piovt + 1 < right) {

stack.push(piovt+1);

stack.push(right);

}

while (!stack.isEmpty()) {

right = stack.pop();

left = stack.pop();

piovt = partitionHole(array,left,right);

if(piovt - 1 > left) {

stack.push(left);

stack.push(piovt-1);

}

if(piovt + 1 < right) {

stack.push(piovt+1);

stack.push(right);

}

}

}

歸并排序

遞歸版

使用遞歸不斷將區(qū)間二分,直到區(qū)間只有一個元素為止,然后將兩個區(qū)間進(jìn)行排序合并,直到將所有區(qū)間合并完。

代碼如下:

public static void mergeSort(int[] array){

int[] dst=new int[array.length];

dst= Arrays.copyOf(array,array.length);

merge(array,dst,0,array.length-1);

for(int i=0;i

array[i]=dst[i];

}

private static void merge(int[] src,int[] dst,int start,int end){

if(start>=end) return;

int mid=(start+end)>>1;

merge(dst,src,start,mid);

merge(dst,src,mid+1,end);

int i=start,j=mid+1,k=start;

while(i<=mid || j<=end){

if(j>end || (i<=mid && src[i]

dst[k++]=src[i++];

else

dst[k++]=src[j++];

}

}

時間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(N)?

非遞歸版

將整個區(qū)間劃分為長度為1,2,4,8,..........最大為N的小區(qū)間,然后對相鄰的長度為1,2,4,8,..........最大為N的小區(qū)間分別進(jìn)行排序合并,最終就排好序了。

代碼如下:

public static void mergeSortNor(int[] array){

int[] src=array;

int[] dst=new int[array.length];

for(int step=1;step

for(int start=0;start

int mid=Math.min(start+step-1,array.length-1);

int end=Math.min(start+2*step-1,array.length-1);

int i=start,j=mid+1,k=start;

while(i<=mid || j<=end){

if(j>end || (i<=mid && src[i]

dst[k++]=src[i++];

else

dst[k++]=src[j++];

}

}

int[] tmp=src;

src=dst;

dst=tmp;

}

for(int i=0;i

array[i]=src[i];

}

時間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(N)?

計(jì)數(shù)排序

先求出序列中的最大值maxVal和最小值minVal,然后開辟一個長度為maxVal-minVal+1的數(shù)組,值全都初始化為0,然后遍歷整個數(shù)組,將下標(biāo)為每個位置的值減去minVal處的值++,然后再重復(fù)將每個位置的值表示的次數(shù)次,將對應(yīng)的值【下標(biāo)+minVal】存放到原數(shù)組中。

動畫演示:

代碼如下:?

public static void countSort(int[] array) {

int minVal = array[0];

int maxVal = array[0];

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

if(array[i] < minVal) {

minVal = array[i];

}

if(array[i] > maxVal) {

maxVal = array[i];

}

}

int[] count = new int[maxVal-minVal+1];

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

count[array[i]-minVal]++;

}

int index = 0;

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

while (count[i] > 0) {

array[index] = i+minVal;

index++;

count[i]--;

}

}

}

時間復(fù)雜度:O(N)

空間復(fù)雜度:O(N)?

柚子快報(bào)激活碼778899分享:JAVA 詳解常見排序

http://yzkb.51969.com/

文章來源

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19560430.html

發(fā)布評論

您暫未設(shè)置收款碼

請?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄