排序算法思路及代碼實現

最近身邊的朋友都在聊算法,突然想把幾個大學接觸到的排序算法思路整理一下(大學那會兒只能理解,還沒辦法編程實現)。

  • 快速排序算法gim

通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列

1.設定兩個指針變量(下標爲0,length-1),指向數組左右兩邊,且數組一個值作爲指標(劃分左右的參照)

2.從右邊high指向的值和tmp比較,high小則值複製給low,low向前移一位,且一下次從low位置開始比較,大於等於則high指針向左移一位,繼續比較

3.此時比較low指針和指標的大小,如果low指向值大於指標值(23),將low複製給high指向值,high向左移一位。如果low指向值小於指標值(23),low向右移動一位。直到low=high,將指標值賦給low指向的數組下標。結束一次的排序

4.一次排序過後,會出現以指標值爲基準,左邊小於指標值,右邊大於指標值(左右兩邊爲無序,需要遞歸排序)

實現代碼:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class QuickSort {

    public static void main(String[] args) {
        int[] nums = {55,34,45,76,87,45,23,23,45,3,23,2,2,2,34,56,7,8,90,54,3,98,4,2,223,5,54,223};
        System.out.println("begin :nums:" + Arrays.toString(nums));
        //第一次排序取整個數組,下標從0到數組最後
        nums = quickSort(nums,0 , nums.length - 1);
        System.out.println("  end :nums:" + Arrays.toString(nums));
    }

    /**
     * desc:快速排序
     * @param nums
     * @return
     */
    public static int[] quickSort(int[] nums, int low, int high){
        //當要排序的數組左下標和又下標重合時,表示長度爲1,不做排序
        if(low >= high)
            return nums;
        int low_ = low , high_ = high;
        //將數組第一位作爲臨時變量(即劃分左小又大的對比指標)
        int tmp = nums[low];
        //控制和指標對比的元素索引方向(low or high)
        boolean isLeft = false;

        //下標重合時,退出比較
        while(low < high){

            //數組左邊和指標的大小比較
            if(isLeft){
                //數組左指針指向的值小於指標值,指針向後移一位,繼續比較
                if(nums[low] < tmp){
                    low ++;
                    continue;
                }else{
                    //左指針值大於指標值,複製到右指針的位置,然後改變方向從比較指標右邊的值
                    nums[high--] = nums[low];
                    isLeft = !isLeft;
                    continue;
                }
            }else{//數組右邊和指標的大小比較
                //右指針值大於指標值,右指針向左移動一位
                if(nums[high] >= tmp){
                    high --;
                    continue;
                }else{//右指針小於指標值,將右指針值複製給左指針,並改變方向,比較指標左邊部分的值
                    nums[low] = nums[high];
                    isLeft = !isLeft;
                    continue;
                }
            }
        }
        //比較完後發現low下標對應的值有重複,將指標值複製給low對應的下標
        nums[low] = tmp;

        //第一次排序後,以指標爲基準,左小右大(左右部分無序,需要在排序)
        //當左邊的數組大於2個數的時候,對左邊進行遞歸排序
        if(low > 2){
            //對數組的最左邊到指標左邊一位部分進行遞歸排序(指標左邊部分的排序)
            quickSort(nums,low_ , low - 1);
        }
        if(low < nums.length - 2){
            //對指標右邊一位到數組最右邊部分進行遞歸排序(指標右邊部分的排序)
            quickSort(nums,low + 1,high_);
        }
        return nums;
    }
}

  • 選擇排序

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到全部待排序的數據元素排完。 選擇排序是不穩定的排序方法

1.指針(index)指向數組最左邊,將指針指向元素和index+1元素一次進行比較,如果元素小於指針元素,互換位置(5比31小互換位置)

2.比較比較元素小標右移動(下標+1),和指針(index)繼續比較,小於指針元素的互換位置,一輪比較之後,會出現一個最小值爲指針指向值,指針右移一位(index+1),進入下一輪指針和其右邊的數組大小比較。

3.當指針執行數組最後一個元素時,排序結束

 

代碼實現:

package com.lirong.sort;

import java.util.Arrays;

/**
 * desc:SelectionSort
 * author:lirong
 * data:2019/05/09
 */
public class SelectionSort {

    public static void main(String[] args) {
        int[] nums = {12,34,34,4554,76,7688,45,34,234,232,342,3,23,12,1223,324,432,2};
        System.out.println("begin:" + Arrays.toString(nums));
        selectionSort(nums);
        System.out.println("end:" + Arrays.toString(nums));
    }

    /**
     * desc:選擇排序
     * @return
     */
    public static int[] selectionSort(int[] nums){
        //指針第一次指向數組最左邊邊元素
        int index = 0, tmp ;
        //當指針移動到數組最右邊,排序結束
        while(index < nums.length - 1){
            //遍歷指針右邊的元素,比指針指向的元素小的,互換位置,每次遍歷完,指針向左移一位
            for(int i = index + 1 ; i < nums.length ; i++){
                if(nums[index] > nums[i]){
                    tmp = nums[i];
                    nums[i] = nums[index];
                    nums[index] = tmp;
                }
            }
            //每次遍歷之後,會出現一個最小的元素
            index ++;
        }
        return nums;
    }
}

三、冒泡排序

它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果他們的順序(如從大到小、首字母從A到Z)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成

  1. 指針指向數組最後一個元素,讓其與前一個元素比較。如果前一個元素大於指針元素,則交換位置。否則指針向前移一位(3比8小,不做交換)
  2. 指針向前移一位,繼續做比較(71比3大,互換位置)
  3. 以此比較下去,最後出現在數組最左邊會是一個最小的元素(如圖)
  4. 進入第二輪比較,指針仍舊從最末尾開始比較(此時比較到左邊第二個元素時停止(因爲最左邊元素(既下標爲0的元素) 已經是數組中最小的,不需要比較了))。

Ps:當從右到左一輪比較下來,都沒有發生過數據交換,說明數組已經是有序的,直接推出排序即可.

插入排序

思想:將索引指向的值與前面已經有序的值進行比較(從最右邊,最大的值開始)。如果該值比索引值大,將他賦值給他後一位值,對比值向左移一位。直到對比的值小於索引值,將索引值賦值給對比值的上一位(上一位已經賦值給了他的再上一位)。

 

示例:

1,。索引剛開始指向下標爲1的,從索引左邊數組最右邊(下標設爲j)開始比較(第一次左邊數組只有一個元素,將索引值(3)存入tmp)==如果對比值大,對比值賦值給他的後一位。然後對比值下標減一(第一次j=0,減一後爲-1,結束循環)。然後將tmp的值賦給j+1

  1. 此時數組如圖2.索引右移一位,指向2,開始新一輪的比較(此時j=1,如圖3).比較索引值tmp(2)和j=1的值(7),對比值大,將對比值賦值給他後一位,如圖4。
  2. 對比值下標減一,繼續比較(3>tmp=2),將對比值(3)賦值給他後一位,如圖5.
  3. 對比值下標減一(此時j--=-1<0),結束循環.
  4. 最後將tmp賦值給j++=0
  5. 一輪插入結束,索引值向右移一位,繼續比較

代碼實現:

package com.lirong.sort;

import java.util.Arrays;

/**
 * author:lirong
 * data:2019/5/14
 * desc:insertion soort
 */
public class InsertionSort {

    public static void main(String[] args) {
        int[] nums = {55,34,45,76,87,45,23,23,45,3,23,2,2,2,34,56,7,8,90,54,3,98,4,2,223,5,54,223};
        System.out.println("begin :nums:" + Arrays.toString(nums));
        //第一次排序取整個數組,下標從0到數組最後
        nums = insertionSort(nums);
        System.out.println("  end :nums:" + Arrays.toString(nums));
    }

    /**
     * desc:插入排序
     * @param nums
     * @return
     */
    public static int[] insertionSort(int[] nums){

        for(int index = 1 ; index < nums.length ; index++){
            //保存索引值
            int tmp = nums[index];
            //比較值從索引值左邊第一個開始
            int j = index - 1;
            for(; j >= 0; j--){
                //當比較值大於索引值,將比較值賦值給比較值後一直
                if(nums[j] > tmp){
                    nums[j+1] = nums[j];
                }else{//當檢索到比索引值小的元素的時候,將索引值放到比較值後一位(即j+1的位置)
                    break;
                }
            }
            nums[j + 1] = tmp;
        }
        return nums;
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章