面试中常见的查找与排序
生活随笔
收集整理的這篇文章主要介紹了
面试中常见的查找与排序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 二分查找(折半查找),它僅適應于有序的順序表
public static int binSearch(int nums[],int des){
int low = 0;
? int high = nums.length -1;
int middle = 0;
while(low<=high){
middle=(low+high)/2;
if(nums[middle]==des)
return middle;
else if(nums[middle]>des)
high = middle-1;
else
low = middle+1;
}
return -1;
}????????????? - 插入排序(直接插入排序時間復雜度O(n*2),折半排序O(n*2),希爾排序最壞的情況的情況O(n*2))
- 直接插入排序
基本思想:
把n個待排序的元素看成一個有序表和一個無序表,開始時有序表中只有一個元素,無序表中有n-1個元素;排序過程即每次從無序表中取出第一個元素,將它插入到有序表中,使之成為新的有序表,重復n-1次完成整個排序過程。
實例:
0.初始狀態 3,1,5,7,2,4,9,6(共8個數)
?? 有序表:3;無序表:1,5,7,2,4,9,6
1.第一次循環,從無序表中取出第一個數 1,把它插入到有序表中,使新的數列依舊有序
?? 有序表:1,3;無序表:5,7,2,4,9,6
2.第二次循環,從無序表中取出第一個數 5,把它插入到有序表中,使新的數列依舊有序
?? 有序表:1,3,5;無序表:7,2,4,9,6
3.第三次循環,從無序表中取出第一個數 7,把它插入到有序表中,使新的數列依舊有序
?? 有序表:1,3,5,7;無序表:2,4,9,6
4.第四次循環,從無序表中取出第一個數 2,把它插入到有序表中,使新的數列依舊有序
?? 有序表:1,2,3,5,7;無序表:4,9,6
5.第五次循環,從無序表中取出第一個數 4,把它插入到有序表中,使新的數列依舊有序
?? 有序表:1,2,3,4,5,7;無序表:9,6?
6.第六次循環,從無序表中取出第一個數 9,把它插入到有序表中,使新的數列依舊有序?
?? 有序表:1,2,3,4,5,7,9;無序表:6?
7.第七次循環,從無序表中取出第一個數 6,把它插入到有序表中,使新的數列依舊有序?
?? 有序表:1,2,3,4,5,6,7,9;無序表:(空)
代碼:public static void insertSort(int[] a){
int n = a.length;
int i,j;
for(i=1;i<n;i++){
//temp為本次循環待插入有序列表中的數
int temp=a[i];
//尋找temp插入有序列表的正確位置
for(j=i-1;j>=0 &&a[j]>temp;j--){
//元素后移,為插入temp做準備
a[j+1]=a[j];
}
//插入temp
a[j+1]=temp;
}
}? - 折半排序
基本思想:
折半插入算法是對直接插入排序算法的改進,排序原理同直接插入算法:
把n個待排序的元素看成一個有序表和一個無序表,開始時有序表中只有一個元素,無序表中有n-1個元素;排序過程即每次從無序表中取出第一個元素,將它插入到有序表中,使之成為新的有序表,重復n-1次完成整個排序過程。
與直接插入算法的區別在于:在有序表中尋找待排序數據的正確位置時,使用了折半查找/二分查找。、
public static void binaryInsertSort(int[] a){
int n = a.length;
int i,j;
for(i=1;i<n;i++){
//temp為本次循環待插入有序列表中的數
int temp = a[i];
int low = 0;
int high = i-1;
//尋找temp插入有序表的正確位置,使用二分查找法
while (low<=high) {
int mid = (low + high) / 2;
if (a[mid] > temp) {
high = mid - 1;
} else {
low = mid + 1;
}
}
for(j=i-1;j>=low;j--){
//元素后移,為插入temp做準備
a[j+1]=a[j];
}
//插入temp
a[low]=temp;
}
}? - 希爾排序
基本思想:
希爾排序的實質就是分組插入排序,又稱縮小增量法。
將整個無序序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然后依次縮減增量再進行排序,待整個序列中的元素基本有序時,再對全體元素進行一次直接插入排序。
因為直接插入排序在元素基本有序的情況下,效率是很高的,因此希爾排序在時間效率上有很大提高。
實例:
無序序列:int a[] = {3,1,5,7,2,4,9,6};
第一趟時: n=8; gap=n/2=4; 把整個序列共分成了4個子序列{3,2}、{1,4}、{5,9}、{7,6}
第二趟時:gap=gap/2=2; 把整個序列共分成了2個子序列{2,5,3,9}、{1,6,4,7}
第三趟時:對整個序列進行直接插入排序
希爾排序是不穩定的
private void shellSort2(int[] a){
int n=a.length;?
int i,j,k,gap;
for(gap=n/2;gap>0;gap/=2){
for(i=0;i<gap;i++){?
for(j=i+gap;j<n;j+=gap){
int temp = a[j];
for(k=j-gap;k>=0 && a[k]>temp;k-=gap){
a[k+gap]=a[k];
}
a[k+gap]=temp;
}
}
}
}?
- 直接插入排序
- 交換排序(冒泡排序時間復雜度O(n*2),快速排序最好是O(log(n+1))向上取整,最壞是O(n*2),平均情況為O(nlog(n))
- 冒泡排序
基本思想:
在要排序的一組數中,對當前還未排好序的范圍內的全部數據,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的數往上冒。即依次比較相鄰的兩個數,若發現它們的排序與排序要求相反時,就將它們互。
實例:
待排序數組 int a[] = {49,38,65,97,76,13,27,32};
共 N=8 個數據,需要 N-1=7 趟排序,第 i 趟排序共比較 N-i 次
每趟排序都會找出一個 待排序數據 中的較大值
?
第一趟排序:
第1次比較調整:49和38比較,49>38,交換位置: 38 49 65 97 76 13 27 32
第2次比較調整:49和65比較,49<65,不交換位置: 38 49 65 97 76 13 27 32
第3次比較調整:65和97比較,65<97,不交換位置: 38 49 65 97 76 13 27 32
第4次比較調整:97和76比較,97>76,交換位置: 38 49 65 76 97 13 27 32
第5次比較調整:97和13比較,97>13,交換位置: 38 49 65 76 13 97 27 32
第6次比較調整:97和27比較,97>27,交換位置: 38 49 65?76 13 27 97 32
第7次比較調整:97和32比較,97>32,交換位置: 38 49 65?76 13 27 32 97
第二趟排序:
第1次比較調整:38和49比較,38<49,不交換位置: 38 49 65?76 13 27 32 97
第2次比較調整:49和65比較,49<65,不交換位置: 38 49 65?76 13 27 32 97
第3次比較調整:65和76比較,65<76,不交換位置: 38 49 65?76 13 27 32 97
第4次比較調整:76和13比較,76>13,交換位置: 38 49 65 13 76 27 32 97
第5次比較調整:76和27比較,76>27,交換位置: 38 49 65 13 27 76 32 97
第6次比較調整:76和32比較,76>32,交換位置: 38 49 65 13 27 32 76 97
第三趟排序:
第1次比較調整:38和49比較,38<49,不交換位置: 38 49 65 13 27 32 76 97
第2次比較調整:49和65比較,49<65,不交換位置: 38 49 65 13 27 32 76 97
第3次比較調整:65和13比較,65>13,交換位置: 38 49 13 65 27 32 76 97
第4次比較調整:65和27比較,65>27,交換位置: 38 49 13 27 65 32 76 97
第5次比較調整:65和32比較,65>32,交換位置: 38 49 13 27 32 65 76 97
第四趟排序:
第1次比較調整:38和49比較,38<49,不交換位置: 38 49 13 27 32 65 76 97
第2次比較調整:49和13比較,49>13,交換位置: 38 13 49 27 32 65 76 97
第3次比較調整:49和27比較,49>76,不交換位置: 38 13 27 49 32 65 76 97
第4次比較調整:49和32比較,49>32,交換位置: 38 13 27 32 49 65 76 97
第五趟排序:
第1次比較調整:38和13比較,38>13,交換位置: 13 38 27 32 49 65 76 97
第2次比較調整:38和27比較,38>27,交換位置: 13 27 38 32 49 65 76 97
第3次比較調整:38和32比較,38>32,交換位置: 13 27 32 38 49 65 76 97
第六趟排序:
第1次比較調整:13和27比較,13<27,不交換位置: 13 27 32 38 49 65 76 97?
第2次比較調整:27和32比較,27<32,不交換位置: 13 27 32 38 49 65 76 97
第七趟排序:
第1次比較調整:13和27比較,13<27,不交換位置: 13 27 32 38 49 65 76 97
Java實現:
public static void bubbleSort(int []a){
int n =a.length;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]>a[j]){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}
?? - 快速排序
基本思想:
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
1.設置 low=0, high=N-1。
2.選擇一個基準元素賦值給temp,即temp=a[low]。
3.從high開始向前搜索,即由后開始向前搜索(high--),找到第一個小于temp的值,將a[high]和a[low]交換。
4.從low開始向前后搜索,即由前開始向后搜索(low++),找到第一個大于temp的值,將a[high]和a[low]交換。
5.重復第3步和第4步,直到 low==high ,3,4步中,若沒找到符合條件的值,執行 high-- 或 low++ ,直到找到為止。進行交換時 low和high的位置不變。當low==high時循環結束。
Java實現:?
public static int getMiddle(int[]numbers,int low,int high){
int temp = numbers[low];//數組的第一個作為中軸
while (low<high){
while (low<high && numbers[high]>temp){
high--;
}
numbers[low]=numbers[high];//比中軸小的記錄移到低端
while (low<high &&numbers[low]<temp){
low++;
}
numbers[high]=numbers[low];//比中軸大的記錄移到高端
}
numbers[low]=temp;//中軸記錄到尾
return low;//返回中軸的位置
}
public static void quickSort(int[]numbers,int low,int high){
if(low<high){
int middle = getMiddle(numbers,low,high);//對numbers數組進行一分為二
quickSort(numbers,low,middle-1);//對低字段進行遞歸排序
quickSort(numbers,middle+1,high);//對高字段進行遞歸排序
}
}?
?
?
- 冒泡排序
- 選擇排序
- 簡單選擇排序
算法思想:每趟初始默認設定待排序數列中的第一個元素為最小(或最大)的元素;?
將其與后面的元素逐一進行比較,若其大于(或小于)某一元素,則將這一元素記為最小(或最大)的元素,并按此方式繼續向后比較;?
當所有元素都比較過后,最終記錄的元素即為該趟排序中最小(或最大)的元素,將其與待排序數列中的第一個元素交換位置;?
去除起始位置排序完成的元素,將包含剩余元素的待排序數列按上述步驟進行排序;?
執行(n-1)趟后,所有元素排序完成。
Java實現:
public void sort(int[] arr){
//需要執行的趟次(n-1)
for(int i =0;i<arr.length-1;i++){
//默認設置起始位置為最小
int min=i;
//將當前最小的元素與后面的元素逐一比較
for(int j=i+1;j<arr.length;j++){
//若當前最小元素大于后面的元素,將后面的元素設為最小
if(arr[min]>arr[j]){
min=j;
}
}
//將最小的元素交換到起始位置
int temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
}??
- 簡單選擇排序
總結
以上是生活随笔為你收集整理的面试中常见的查找与排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: URL跟Url的区别
- 下一篇: Spark数据倾斜的完美解决