排序算法思路及代码实现

最近身边的朋友都在聊算法,突然想把几个大学接触到的排序算法思路整理一下(大学那会儿只能理解,还没办法编程实现)。

  • 快速排序算法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;
    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值