三種基礎排序演算法(選擇排序、插入排序、氣泡排序)
注:
圖片轉自點選開啟連結
以下均使用升序介紹。
選擇排序:
從陣列中找到最小的元素,和第一個位置的元素互換。
從第二個位置開始,找到最小的元素,和第二個位置的元素互換。
........
直到選出array.length-1個較小元素,剩下的最大的元素自動排在最後一位。
程式碼實現:
public class Selection {
public static void sort(int[] arr){
for(int i=0; i<arr.length-1; i++) {
int minPos = i;
for (int j = i; j < arr.length; j++) {
if (arr[j] < arr[minPos]) {
minPos = j;//找出當前最小元素的位置
}
}
if(arr[minPos]!=arr[i]) {
swap(arr,minPos,i);
}
}
}
public static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
衍生演算法:
雙向選擇排序(每次迴圈,同時選出最大值放在末尾,最小值放在前方)。
程式碼實現:
public class Selection {
public static void doubleSort(int[] arr){
for(int i=0; i<arr.length/2-1; i++) {
int minPos = i,maxPos = arr.length -i -1;
for (int j = i; j < arr.length -i; j++) {
if (arr[j] < arr[minPos]) {
minPos = j;
}
if(arr[maxPos] <arr[j]){
maxPos = j;
}
}
if(i!=minPos) {
swap(arr,i,minPos);//(1)
}
if(maxPos!=arr.length - i - 1) {
if (maxPos == i){//若當前最大值在迴圈起始位置,則最大值一定在(1)處被交換到了minPos的位置
maxPos = minPos;
}
swap(arr,maxPos,arr.length -i -1);
}
}
}
public static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
插入排序:
從第二個元素開始,將當前元素插入到前面對應位置,使當前元素i
和之前元素形成有序陣列。
比較規則:
正常:
從第一個元素開始,若當前元素i小於有序陣列中的元素j,則從該元素開始將有序陣列依次後移一位,
並將當前元素i放置到該元素j位置。(插入)
簡易:
從有序陣列最後一個元素開始,若當前元素i小於該元素j,則交換當前元素和該元素。
簡易版程式碼實現:
public class Insertion {
public static void sort(int[] arr){
int pos,temp;
for(int i=1;i<arr.length;i++){
pos = i;
while(pos!=0&&arr[pos]<arr[pos-1]){
temp = arr[pos];
arr[pos] = arr[pos-1];
arr[pos-1] = temp;
pos--;
}
}
}
}
氣泡排序:
從前往後,依次比較相鄰的兩個數,把較大的數放到後面。一次迴圈,可以在當前最末尾位置得到一個當前最大值。
程式碼實現:
public class Bubble {
public static void sort(int[] arr){
int temp;
//依次將最大的數放置到陣列末尾,將第二大的數放到倒數第二位...
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]) {
swap(arr,j,j+1);
changed = true;
}
}
}
}
public static void swap(int []arr,int a ,int b){
int temp=arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
程式碼優化:
在某些時候,迴圈還未終止,整個陣列已經排好序,此時應及時終止迴圈。
(冒泡每次都會比較相鄰兩個數並交換次序不對的組,若一次迴圈後,都沒進行交換,則已經完成排序)
優化程式碼實現:
public class Bubble {
public static void sort(int[] arr){
int temp;
boolean changed;
for(int i = 0;i < arr.length-1;i++){
changed = false;
for(int j = 0;j < arr.length-1-i;j++){
if(arr[j]>arr[j+1]) {
swap(arr,j,j+1);
changed = true;
}
}
if(!changed){
break;
}
}
}
public static void swap(int []arr,int a ,int b){
int temp=arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
雞尾酒排序:
雞尾酒是氣泡排序的升級版,該排序從左往右找出最大值後,再從右往左
找出最小值,類似雞尾酒攪拌左右迴圈。在某些情況下,優於氣泡排序,
以序列(2,3,4,5,1)為例,雞尾酒排序只需要訪問兩次(升序降序各一次 )
次序列就可以完成排序,但如果使用氣泡排序則需要四次。
程式碼實現:
public class CockTail {
public static void sort(int[] arr){
//依次將最大的數放置到陣列末尾,將第二大的數放到倒數第二位...
boolean changed;
for(int i = 0;i < arr.length/2;i++){
changed = false;
//從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
for(int j = i;j < arr.length-1-i;j++){
if(arr[j]>arr[j+1]) {
swap(arr,j,j+1);
changed =true;
}
}
if(!changed){
break;
}
for(int j = arr.length-1-i; j > i; j--){
if(arr[j]<arr[j-1]) {
swap(arr,j,j-1);
changed = true;
}
}
if(!changed){
break;
}
}
}
public static void swap(int[] arr, int pos1, int pos2){
int temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
}
}
---------------------
作者:seam22
來源:CSDN
原文:https://blog.csdn.net/weixin_38830382/article/details/79173384
版權宣告:本文為博主原創文章,轉載請附上博文連結!