基础排序算法--冒泡、选择、排序(包括优化后的算法)

排序算法:

一、冒泡排序

1.1 算法步骤:

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

1.2 动图演示:

冒泡排序

1.3 最快:

正序

1.4 最慢:

反序

1.5 代码实现:

    public static void main(String[] args){
        int [] sums = {11,23,43,12,1,6,21,3};
        for (int i = 0; i < sums.length-1; i++) {//和选择排序一样,两两比较,比较N-1轮
            boolean flag = true; 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
        for (int j = 0;j < sums.length-i-1;j++){
            if (sums[j]>sums[j+1]){
                int t = sums[j];
                sums[j] = sums[j+1];
                sums[j+1] = t;
                flag = false;
            }
        }
        if (flag){
            break;
        }
        }
        for (int sum : sums) {
            System.out.println(sum);
        }
    }

二、选择排序

2.1 算法步骤

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

重复第二步,直到所有元素均排序完毕。

2.2 动图演示

选择排序

2.3 代码实现

    public static void SelectionSort (int [] sums){
        //总共要比较N-1轮
        for (int i = 0; i < sums.length-1; i++) {
            int min = i;
            //每轮需要比较的次数N-i
            //下标进行比较
            for (int j = i+1;j < sums.length ;j++){
                if (sums[j] < sums[min]){
                    //记录目前能找到的最小值元素的下标
                    min = j;
                }
            }
            //将找到的最小值和i位置所在的值进行交换
            //如果i不等于最小值,将此时此时的最小值min与i交换,这样就能保证i为最小值。
            //if在第一层循环里面
            if (i!=min){
                int t = sums[i];
                sums[i] = sums[min];
                sums[min] = t;
            }
        }
        for (int sum : sums) {
            System.out.println(sum);
        }
    }

三、插入排序

就和打扑克,人们对手中的牌进行排序一样

3.1 算法步骤

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

3.2 动图演示

插入排序

3.3 代码实现

public static void insertSort(int[] arr){
    for(int i=1;i<arr.length;i++){
        for(int j=i-1;j>=0;j--){
            if(arr[j]>arr[j+1]){
                int t=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=t;
            }
        }
    }
}
    public static void insertSort(int[] sums){
        //从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < sums.length; i++) {//从第二元素开始,可以等于最后一个元素,因为插入的话需要把牌看一遍//i为下标
            //记录要插入的数据
            int temp = sums[i];
            //位置指针
            int pos=i-1;
            //直接将拿的牌放到该放的位置
            while (pos >= 0 && sums[pos]>temp){
                //指针所指的数大于temp
                //把指针后面的数换成指针所指的数
                sums[pos+1]=sums[pos];//覆盖掉原有的,但是temp值被保存了下来
                pos--;//指针继续往前移
            }
            sums[pos+1]=temp;//指针前移以后,把插入的数据放到位置
        }
            for (int sum : sums) {
            System.out.println(sum);
        }
    }

四、JDK排序

java.util.Arrays.sort(数组名); //JDK提供(升序)。

本身提供的升序。

    public static void jdkSort(int[] sums) {

//对数组进行排序
        Arrays.sort(sums);

//升序输出
// for(int i=0; i<a.length; i++) {
// System.out.println(a[i]);
// }

//降序输出,因为JDK排序默认升序(由小到大),所以降序需要倒着遍历输入。
        for(int i=sums.length-1; i>=0; i--) {
            System.out.println(sums[i]);
        }
    }

五、数组的插入

插入的关键在于看是否是在需要后移的元素段后面。

需要知道需要后移元素段的长度size。

三个判断。//1.判断是否在不需要后移的元素段里面

2.判断是否在需要后移的元素段里面3.不在数列长度里面

        //插入
        int[] a = {1,2,4,7,5,0,0};
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个新的元素:");
        int n = input.nextInt();
        System.out.println("请输入插入元素的位置:");
        int pos = input.nextInt();
        int size = 5;//需要知道需要后移元素段的长度
        if (pos>size&&pos<a.length){//判断是否在不需要后移的元素段里面
            a[pos-1]=n;
            for (int i : a) {
                System.out.println(i);
            }
        }else if (pos>=0&&pos<=size){//判断是否在需要后移的元素段里面
            for (int j = size - 1; j >= pos; j--) {//后面的元素依次往后移一个位置,给插入的元素留出位置
                a[j + 1] = a[j];
            }
            a[pos] = n;
            size++;
            for (int i : a) {
                System.out.println(i);
            }
        }else{//不在数列长度里面
            System.out.println("输入有误!");
        }

六、数组的删除

判断:

如果是位置在size-1则直接删除。即位置在需要后移的size段的最后一个

如果位置为size的前面,删除位的后面的数往前移,a[k]=a[k+1],最后一个需要后移的size段变成0,a[size]=0。

        
		int size = 5;
		System.out.println("请输入删除的位置:");
        int p =input.nextInt();
        if (p>0&&p<size){
            if (p==size-1){
                a[p]=0;
            }else {
                for (int k = p;k<size;k++)
                {
                    a[k] = a[k+1];
                }
                a[size]=0;
            }
            for (int i : a) {
                System.out.println(i);
            }

        }else
        {
            System.out.println("输出有误");
        }
   }
            a[size]=0;
        }
        for (int i : a) {
            System.out.println(i);
        }

    }else
    {
        System.out.println("输出有误");
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值