前序:之前由于换工作,面试了几家公司,好多公司都问一下算法的问题,对于java开发来说,用到的算法比较少,大家都比较不熟悉,但是,工作中需要,所有,我整理了一些,大家仅供参考,充实一下自我,提升自己的技术。

一、排序

1.1 排序概述

排序(sorting)的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列。
内部排序和外部排序

一类是整个排序过程在内存储器中进行,称为内部排序;
另一类是由于待排序元素数量太大,以至于内存储器无法容纳全部数据,排序需要借助外部存储设备才能完成,这类排序称为外部排序。
本章介绍的排序方法都属于内部排序

比较排序和非比较排序

大部分排序都是需要通过比较首先来判断大小,作为排序的依据的。

但是也有例外的,比如计数排序、基数排序,不需要进行比较。效率可以做到更高,但是会有一些限制条件,也可能需要更多的空间。

冒泡排序、选择排序、直接插入排序是最基本的三种排序,效率最低,但是算法简单。排序的学习一般从这三种排序算法开始。

【示例1】冒泡排序算法

public class TestBubbleSort1{
    public static void main(String [] args){
        //定义一个无序数组
        int [] arr = {75,87,56,45,89,100,76,34,89,97};
        //排序前输出
        System.out.println("排序前");
        for(int score :arr){
            System.out.print(score+"\t");
        }
        //排序
        //大循环:n个元素排序,则至多需要n-1趟循环
        for(int i=0;i<arr.length-1;i++){
            //小循环:每一趟循环都从数列的前两个元素开始进行比较,
//比较到数组的最后
            for(int j=0;j<arr.length-1;j++){
                //如果前一个大于后一个
                if(arr[j] > arr[j+1]){
                    //交换
                    int temp;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        //排序后输出
        System.out.println("\n排序后");
        for(int score :arr){
            System.out.print(score+"\t");
        }
    }
}
缺点1:每一趟比较都要比较到数组的最后,没有必要,只要比较到无序数列最后即可
缺点2:不管是否有序,都要进行n-1趟循环;
【示例2】完善冒泡排序算法
public class TestBubbleSort2{
    public static void main(String [] args){
        //定义一个无序数组
        int [] arr = {75,87,56,45,89,100,76,34,89,97}; 
        //排序前输出
        System.out.println("排序前");
        for(int score :arr){
            System.out.print(score+"\t");
        }
        //排序
        bubbleSort(arr);       
        //排序后输出
        System.out.println("排序后");
        for(int score :arr){
            System.out.print(score+"\t");
        }
    }    
    public static void bubbleSort(int arr[]){
        //大循环:n个元素排序,则至多需要n-1趟循环
        int temp;
        int i;
        for(i=0;i<arr.length-1;i++){
            //1. 假设有序
            boolean flag = true;
           //2.小循环:每一趟循环都从数列的前两个元素开始进行比较,比较到数组的最后
            for(int j=0;j<arr.length-1-i;j++){
                //如果前一个大于后一个
                if(arr[j] > arr[j+1]){
                    //交换               
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    //发生了交换,数组无序
                    flag = false;
                }
            }
            //3.判断是否有序,有序,退出
            if(flag){
                break;
            }
        }
    }
}
1.3 选择排序

选择排序的算法

1) 整个数列分成两部分:前面是有序数列,后面是无序数列
2) 初始状态下,整个数列都是无序的,有序数列是空
3) 一共n个数,需要n-1趟循环(一趟都不能少)
4) 每比较完一趟,有序数列数量+1,无序数列数量-1
5) 每趟先假设无序数列的第1个元素(整个数列的第i个元素)是最小的,让当前的最小数,从第i+1个元素开始比较,一直比较到最后一个元素。如果发现更小的数,就假设当前数是最小数。
6) 一趟比较完后,将发现最小数和无序数列的第一个数交换(如果最小数不是无序数列的第一个数)

【示例3】选择排序

public class TestSelectSort {
   public static void main(String[] args) {
        //给定无序的数组
        int [] scoreArr = {75,87,56,45,89,100,76,34,89,97};
        System.out.println(Arrays.toString(scoreArr));
        //选择排序
        selectSort(scoreArr);
        System.out.println(Arrays.toString(scoreArr));
    }
    public static void selectSort(int[] scoreArr) {
        //大循环:n个元素排序,则需要n-1趟循环
        for(int i=0;i<scoreArr.length-1;i++){
            //第i趟先假设第i个最小
            int minIndex = i;
            //从第i+1个元素开始,依次使用最小元素和每元素比较,一直比较到最后
            for (int j = i+1; j <scoreArr.length ; j++) {
                if(scoreArr[minIndex] > scoreArr[j]){
                    minIndex = j;
                }
            }
           //一趟比较完后,或者最小值的索引,如果不是第i个,就交换
            if(minIndex !=i){
                int temp;                 temp = scoreArr[i]; 
                scoreArr[i] = scoreArr[minIndex];  scoreArr[minIndex] = temp;
            }
        }
    }
}

2、递归

public class TestRecursion1 {
    public static void main(String[] args) {
        //使用循环求n!
        int n = 6;
        int fac = 1;
        for(int i=1;i<=n;i++){
            fac = fac * i;
        }
        System.out.println(fac);        
        //使用递归求n!
        int result = fac(n);
        System.out.println(result);
    }    
    public static int fac(int n){
        int result;
        if(n==1){
            result  = 1;
        }else{
            result =  n * fac(n-1);
        }
        return result;    
    }
}

静待后续