面试中简单的排序还被面试官虐???

1、求数组中的最大值

emm…先来个简单点的算法热热身.奥利给

//求数组的最大值和最小值public class Test5{    public static void main(String[] args){    
    int[]num={12,3,54,67,88,34};    int max=max(num);    int min=min(num);
    System.out.println(max);
    System.out.println(min);
    }    public static int max(int[] num){        int max=num[0];        int numLen=num.length;        for(int i=1;i<numLen;i++){            if(num[i]>max)
                max=num[i];
        }        return max;
    }    public static int min(int[] num){        int min=num[0];        int numLen=num.length;        for(int i=1;i<numLen;i++){            if(num[i]<min)
                min=num[i];
        }        return min;
    }
}

2、冒泡排序

数组排序在面试中也会经常会遇到到,面试官通过基本的排序算法来了解你对程序基本算法的了解,我们先学习一下最稳定的排序方式冒泡排序!

//冒泡排序第一版public class Test6{    /*
    比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
    针对所有的元素重复以上的步骤,除了最后一个。
    持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

    5 8 6 3 9 2 1 7 一堆乱序的数字,对他排序
    5 6 3 8 2 1 7 9 第一轮
    5 3 6 2 1 7 8   第二轮
    3 5 2 1 6 7       第三轮
    3 2 1 5 6       第四轮
    2 1 3 5         第五轮
    1 2 3           第六轮         现在顺序已经出来了 但是我们不能保证其他数组排到 第六轮 就能排出来
    1 2             第七轮
    */
    public static void main(String[] args){    
        int[] nums={5,8,6,3,9,2,1,7};        //外循环控制轮数
        int times=nums.length-1;//轮数等于数组长度减1
        for(int i=0;i<times;i++){            for(int j=0;j<times-1-i;j++){                if(nums[j]>nums[j+1]){//交换位置
                    nums[j]=nums[j]+nums[j+1];
                    nums[j+1]=nums[j]-nums[j+1];
                    nums[j]=nums[j]-nums[j+1];
                }
            }
        }        //输出结果
        for(int n:nums){
            System.out.println(n);
        }
    }

}

我们发现第六轮已经排完了,第七轮就没有必要排了嘛,但是算法还是认真的执行了第七轮比较了下去,在这种情况下我们可衣判断一下数组是否有序,如果有序就直接结束循环,,提高效率

//冒泡排序第二版public class Test6{    /*
    我们用一个bool来标记是否有序,初始值为true
    */
    public static void main(String[] args){    
        int[] nums={5,8,6,3,9,2,1,7};        boolean isSorted=true;        //外循环控制轮数
        int times=nums.length-1;//轮数等于数组长度减1
        for(int i=0;i<times;i++){            for(int j=0;j<times-1-i;j++){                if(nums[j]>nums[j+1]){//交换位置
                    nums[j]=nums[j]+nums[j+1];
                    nums[j+1]=nums[j]-nums[j+1];
                    nums[j]=nums[j]-nums[j+1];
                    isSorted=flase;//如果发生了数组交换,所以数组不是有序把 标志变成false
                }
            }            if(isSorted){                break;
            }
        }        //输出结果
        for(int n:nums){
            System.out.println(n);
        }
    }

}

这只是冒泡排序的一个点,为了说明问题我们用一个新数列来讲解一下,
3 4 2 1 5 6 7 8
这个数列后四个是有序的,前边四个是无序的但是,我们每一轮排序的时候,后边四个都需要比较
第一轮
3和4比较 4和2比较 4和1比较 4和5比较 5和6比较 6和7比较 7和8比较
第一轮结果
3 2 1 4 5 6 7 8
第二轮
3和2比较 3和1比较 3和4比较 4和5比较 5和6比较 6和7比较 7和8比较
第二轮结果
2 1 3 4 5 6 7 8
第三轮
2和1比较 2和3比较 3和4比较 4和5比较 5和6比较 6和7比较 7和8比较
第三轮结果
1 2 3 4 5 6 7 8
我们发现什么了 发现后边都有顺序了但是我们还是比较了很多次,冒泡排序第二个优化的点就是数列有序区的界定
我们可以在每一轮排序后,记录一下数组最后一次交换的位置,该位置就是无序数列的边界,再往后就是有序区了,直接上代码

//冒泡排序第三版public class Test6{    /*
    我们用一个bool来标记是否有序,初始值为true
    */
    public static void main(String[] args){    
        int[] nums={3,4,2,1,5,6,7,8};        boolean isSorted=true;        //外循环控制轮数
        //无序序列的边界,每次比较到这里就可以了
        int sortedBorder=nums.length-1;        int times=nums.length-1;//轮数等于数组长度减1
        for(int i=0;i<times;i++){            for(int j=0;j<sortedBorder;j++){                if(nums[j]>nums[j+1]){//交换位置
                    nums[j]=nums[j]+nums[j+1];
                    nums[j+1]=nums[j]-nums[j+1];
                    nums[j]=nums[j]-nums[j+1];
                    isSorted=flase;//如果发生了数组交换,所以数组不是有序把 标志变成false
                    sortedBorder=j
                }
            }            if(isSorted){                break;
            }
        }        //输出结果
        for(int n:nums){
            System.out.println(n);
        }
    }

}

为什么说冒泡是稳定的排序算法呢,如果数组中有相同的元素的话 排序完他俩的位置没有改变,
5 8 8 3 9 2 1 7,现在我们给第一个8标号 1, 第二个8标号2 ,使用冒泡排完序,数组的第1个位置还是1号的8,第2个位置还是2号的8,所以它的排序是稳定,既然有稳定的排序方式,那么就有不稳定的排序方式,来我们继续。。

3、选择排序

//选择排序public class Test7{    /*每一趟从待排序的数据元素中选出最小(或最大)的一个元素,
    顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
    选择排序是不稳定的排序方法。
    34,4,56,17,90,65
    4 34 56 17 90 65 第一轮
    4 17 56 34 90 65 第二轮
    4 17 34 56 90 65 第三轮
    4 17 34 56 90 65  第四轮
    4  17 34 56 65 90 第五轮
    */
    public static void main(String[] args){    
        int[] nums={34,4,56,17,90,65};//待排序的数列
        int minIndex=0;//用于记录每次比较的最小值下标
        int times=nums.length-1;        //控制轮数
        for(int i=0;i<times;i++){
            minIndex=i;//每轮假设一个最小值下标
            for(int j=i+1;j<nums.length;j++){                if(nums[minIndex]>nums[j]){
                    minIndex=j;
                }
            }            //判断需要交换的数下标是否为自己
            if(minIndex!=i){
                nums[minIndex]=nums[minIndex]+nums[i];
                nums[i]=nums[minIndex]-nums[i];
                nums[minIndex]=nums[minIndex]-nums[i];
            }

        }        //输出结果
        for(int n:nums){
            System.out.println(n);
        }
    }

}

选择排序,它比较的次数和冒泡是一样的但是一轮就交换了一次,所以它效率比较高,但是它不稳定,很有可能两个相同的元素他们位置会互换,如果不考虑稳定性,建议使用选择排序!
选择排序排完,咱们趁热打铁,直接插入排序..

4、直接插入排序算法

插入排序思路: 34,4,56,17,90,65


第一轮
从下标1 开始 把下标1当做操作数,把操作数用一个临时变量存起来,然后和前一个比较,如果第0个数大于操作数,那么整个数列往后移,怎么个移法呢,就是操作数的下标位置等于 第0个数   4变成34,第一轮就算结束了,然后看发生变化的变量是操作数自己吗不是就吧操作数赋给它
第二轮
操作数变成了56, 操作数和34比 34小,所以操作数一定大于34 前边的所有的数,所以就不用比较了,第二轮结束,也不用交换变量
第三轮
操作数变成了17, 操作数和56 比 操作数比较小,所以56往后移,17位置的数变成56,然后操作数再和34比,比34还小,那么34往后移最开始的56变成34,操作数和4比,操作数大于4,结束第三轮 然后最后往后移的数的位置变成操作数,也就是17,第三轮结束,依次往下进行,我们看代码

//插入排序public class Test8{    /*

    34,4,56,17,90,65

    */
    public static void main(String[] args){    
        int[] nums={34,4,56,17,90,65};//待排序的数列

        int times=nums.length;        for(int i=1;i<times;i++){            int temp=nums[i];//记录操作数
            int j=0;            for(j=i-1;j>=0;j--){                if(nums[j]>temp){
                    nums[j+1]=nums[j];
                }else{                    break;
                }
            }            //判断需要交换的数下标是否为自己
            if(nums[j+1]!=temp){
                nums[j+1]=temp;
            }

        }        //输出结果
        for(int n:nums){
            System.out.println(n);
        }
    }

}

小结

这几种常用的排序算法,先介绍到这里,肯定有小伙伴问?有没有比冒牌要快的排序算法呢?那是当然有啦,比如快速排序,归并排序和堆排序等等.由于有写算法设计到数据结构,所以不打算在这个系列里写,但是肯定会写的.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值