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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手写快速排序

發布時間:2023/12/8 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手写快速排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

快速排序是一種很重要的排序算法,我花了不少時間去理解并總結它,希望可以通過圖文的方式讓你快速理解快速排序,并能手擼一個快排。

快速排序簡介

快速排序是一種很不錯的排序算法,算法復雜度為n*logn。快排使用了分而治之的思想,每次排序是都找到一個基準(我們學習時經常使用第一個作為基準),然后把小于基準的元素放到基準元素的左邊,大于基準的元素放到基準元素的右邊,這樣一次排序下來,基準元素左邊都是小于(等于)基準的數,基準右邊的元素都是大于(等于)基準的元素了。快速排序關鍵點就是找到這樣一個基準并將其放到恰到的位置。

算法思路

定義一個快速排序函數,arr是要排序的數組,l指向要排序的數組最左邊的元素,r指向要排序的數組最右邊的元素。

public static void quick_sort(int arr[],int l,int r){if(l >= r) return;//p為快速排序返回的基準的位置int p = partition2(arr,l,r);//對基準左邊的數進行快排quick_sort(arr,l,p-1);//對基準右邊的數進行快排quick_sort(arr,p+1,r);}

那么現在關鍵就是這么實現這個partition2函數

假設現在有一個數組arr[]:

我們每次都取第一個元素為基準元素,定義i指向基準的下一個元素位置,j指向最后一個元素的位置:

i 從左向右掃描,如果arr[i] <= v , i++
j從右向左掃描,如果 arr[j] > v ,j–
直到i指向一個大于v的元素,j指向一個小于j的元素,且 這個過程中 i <= j

此時i左邊(除基準元素)都是小于v的,j右邊都是大于v的,現在只需要交換arr[i]與arr[j]的位置,就可以把小于v的放左邊,大于v的放右邊,然后i++,j–

繼續比較,此時arr[i] = 4 < 5,i++ ,arr[j] > 5 j–

到這里 i > j 了,退出循環,最后把基準v與arr[j]交換位置,即把v放到了小于v的元素的最后一個,此時一次快速排序就完成了。

代碼實現

//快速排序,另一種從前后掃描的public static int partition2(int arr[],int l,int r){//基準元素設為第一個int v = arr[l];//i指向基準的下一個元素,j指向最后一個元素int i = l+1,j = r;while(true){while(i <= r && arr[i] < v) i++;while(j > l && arr[j] > v) j--;//循環終止條件if(i > j) break;//交換arr[i]與arr[j]int t = arr[i];arr[i] = arr[j];arr[j] = t;i++;j--;}//將基準元素與arr[j]交換int t = arr[l];arr[l] = arr[j];arr[j] = t;//返回基準元素所在位置return j;}

快速排序的幾個問題

1、對于幾乎有序的數組,快速排序返回的基準的位置都在第一個或很靠前的位置,使得對數組的切分不夠平均,可能使得快速排序的時間復雜度退到o(n^2) , 對于這種情況,可以在排序時選取數組中的一個隨機位置的數作為基準數。

2、對于數組中的元素有很多相等元素時,也會導致快排對數組的切分不平衡,此時快排的時間復雜度也可能退到o(n^2) , 對于這種情況,可以使用三路快速排序,把小于基準v的放左邊,等于v的放中間,大于v的放右邊,就避免了左右不平衡的問題。

3、在進行快排時候,當數比較少的時候,使用插入排序代替快排可提高算法效率。

三路快速排序

三路快速排序針對數組中有很多相等元素時照樣能有很不錯的效率,其主要思想就是將數組中的數分成三個部分:小于基準v的放左邊,等于v的放中間,大于v的放右邊。
代碼

/*** 三路快速排序,確定基準v后將數分成"小于v的","等于v的","大于v的"* @param arr* @param l* @param r*/public static void quickSort3Ways(int arr[],int l,int r){if(l >= r) return;int v = arr[l];//初始時,i指向基準位置,j指向最后一個元素的下一個位置int i = l , j = r + 1;//cur指向當前要進行比較的元素int cur = i + 1; while(cur < j){//如果當前元素大于基準元素,將次元素放到后面去,j--if(arr[cur] > v){int t = arr[cur];arr[cur] = arr[j-1];arr[j-1] = t;j--;//如果當前元素小于v,將它放到i前面去}else if(arr[cur] < v){int t = arr[cur];arr[cur] = arr[i+1];arr[i+1] = t;i++;cur++;//若當前元素等于v,當前指針cur后移即可}else{cur++;} }//最后交換arr[l](基準元素)與arr[i]的位置int t = arr[i];arr[i] = arr[l];arr[l] = t;//對基準元素左邊快排quickSort3Ways(arr,l,i-1);//對基準元素右邊快排quickSort3Ways(arr,j,r);}

總結

以上是生活随笔為你收集整理的手写快速排序的全部內容,希望文章能夠幫你解決所遇到的問題。

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