常用的几种算法

1.冒泡排序

//冒泡排序
/*
具体思路:
    (1) 整个数列分成两部分:前面是无序数列,后面是有序数列
    (2) 初始状态下,整个数列都是无序的,有序数列是空
    (3) 如果一个数列有n个元素,则至多需要n-1趟循环才能保证数列有序
    (4) 每一趟循环可以让无序数列中最大数排到最后,(也就是说有序数列的元素个数增加1)
    (5) 每一趟循环都从数列的第一个元素开始进行比较,依次比较相邻的两个元素,比较到无序数列的末尾即可(而不是数列的末尾)
    (6) 如果前一个大于后一个,交换
*/
public class Test02 {
    public static void main(String[] args) {

        int[] a ={30,25,40,15,100,65,20};  //定义数组并给出对应的值
        int count=0; //定义一个统计次数的变量
        for (int j = 0; j < a.length-1; j++) {  //外层循环控制是的几趟,并且长度-1,下标是从0开始的,并且长度超出就会跳出循环
            //内层循环是控制比较的次数,并且长度-1,下标是从0开始的
            //当最外层循环执行完之后,就-j,表示这趟已经执行完了,再不需要挨个值和后面一个值比较,比较节省空间
            boolean flag = true;  //定义一个boolean为true,表示顺序已经排好
            for (int i = 0; i <a.length-1-j; i++) {
                count++; //每次进入循环就+1,统计走了多少次
                if (a[i]>a[i+1]){  //判断第一个下标的数组的值和第二个下标的数组的值做判断,数组的值大于就进入判断进行值交换,否则不进入判断,直接跳出循环,以此类推
                    int temp;   //定义中间变量
                    temp=a[i];  //a[1]=15,将这个15赋值给temp
                    a[i]=a[i+1]; //a[2]=4,将这个4赋值给下标a[1],a[2]现在的值为4
                    a[i+1]=temp; //将15这个数赋值给a[2],a[2]现在的值为15,然后都是以此类推!
                    flag=false;  //false,表示顺序没有排好,就要进行比较
                }

            }
            if(flag){   //判断里面的循环是否已经排好了顺序,排好了,就直接跳出层循环,就不需要再比较
                break;
            }
            System.out.println(Arrays.toString(a)); //快速遍历
        }
        System.out.println(count); //统计的次数

    }
}

2.选择排序

//选择排序
/*
具体思路:
    (1) 整个数列分成两部分:前面是有序数列,后面是无序数列
    (2) 初始状态下,整个数列都是无序的,有序数列是空
    (3) 一共n个数,需要n-1趟循环(一趟都不能少)
    (4) 每比较完一趟,有序数列数量+1,无序数列数量-1
    (5) 每趟先假设无序数列的第1个元素(整个数列的第i个元素)是最小的,让当前的最小数,从第i+1个元素开始比较,一直比较到最后一个元素。如果发现更小的数,就假设当前数是最小数。
    (6) 一趟比较完后,将发现最小数和无序数列的第一个数交换(如果最小数不是无序数列的第一个数)
 */
public class Test02 {
    public static void main(String[] args) {
        int[] a ={30,25,40,15,100,65,20};  //定义一个数组并赋值
        int count=0;
        for (int j = 0; j <a.length-1 ; j++) {  //外层循环比较的是趟数
            int minIndex=j; //默认下标为0的值为最小值进行比较
            for (int i = minIndex+1; i <a.length; i++) {  //默认每次循环的最小值下标+1
                //这个判断主要是交换下标
                if (a[minIndex]>a[i]){  //将默认最小值索引为a[0]=30和a[1]=25做比较,大于进入判断条件,否则不进入,结果大于,以此类推
                    minIndex=i;   //把最小值变量替换成指定下标,就好比15的下标和30的下标交换位置
                }
                count++;
            }
            //这个判断主要是交换值的
            if (minIndex!=j){   //如果不等于0,就说明下标进行交换了,然后进行入判断条件
                int temp;   //定义一个中间变量
                temp=a[j]; //a[0]=30赋值给temp,temp现在的值为30
                a[j]=a[minIndex]; //a[3]的值15赋值给a[0]=30,现在a[0]=15,a[0]和a[3]的值都为15
                a[minIndex]=temp; //将30赋值给a[3],所以现在的a[3]的值为30
            }
            System.out.println(Arrays.toString(a));
        }
        System.out.println(count);
    }

}

3.插入排序

//快速排序
/*
具体思路:
	1. 选择要排序数组的左边第一个元素作为基准
	2. 然后从要排序数组的最右边开始进行检索,找比基准数小的,找到后就先停止检索
	3. 然后从要排序数组的最左边开始进行检索,找比基准数大的,找到后就先停止检索	
	4. 将上面两个找到的元素进行交换	
	5. 交换完后,接着使用同样的方式进行检索	
	6. 当左边索引 和 右边索引相等时,停止检索,并且将基准数和相等的这个索引元素进行交换
	7. 然后发现,在相遇的这个位置,左边的元素都比基准数小,右边	的元素都比基准数大			
接下来,接着分别对相遇索引的左边 和 相遇索引的右边 进行同样的快速排序操作!
 */
public class Test01 {
    public static void main(String[] args) {
        int[] arr={33,17,9,88,77,39};  //定义一个数组长度为6,并且赋了值

        bb(arr,0,arr.length-1);  //定义传递的参数和左右下标,传递的参数分别为:数组变量,左侧长度为0,右侧长度为总长度5

        System.out.println(Arrays.toString(arr));  //快速遍历数组
    }

    public static void bb(int[] arr,int left,int right){  //定义一个静态方法,分别接受传过来的参数arr={33,17,9,88,77,39},left:0,right:5
        //如果左侧下标比右侧下标大 直接停止即可
        if (left>right){  //判断最左侧的数是否大于右侧,大于进入判断语句,并返回bb方法,小于就不进入
            return;
        }
        int l=left; //将左侧下标0赋值给l
        int h=right; //将右侧下标5赋值给h
        int base=arr[l]; //指定数组a[0]下标这个数的值33赋值给base

        while(l<h){  //循环的条件,如果左侧长度小于右侧长度,就进入循环,否则不进入
            while (arr[h]>=base&&l<h){ //右侧的值如果大于基数时右侧下标--
                h--;
            }
            //如果出了循环证明在右侧找到了比基数小的数
            if (l<h){
                arr[l]=arr[h]; //把右侧的值赋值给左侧的位置
            }
            //左侧判断的实现 左侧的数字比基数小 这个时候把左侧的下标++
            while (arr[l]<=base&&l<h){
                l++;
            }
            //如果出了while循环证明在左侧找到了比基数大的值
            if (l<h){
                arr[h]=arr[l]; //把左侧的值赋值给右侧
            }
            //如果出现等于情况 我们就把基数直接赋值给指定下标
            if (l>=h){
               arr[l]=base;
            }
        }
        //左侧的比较
        bb(arr, left, l-1);
        //右侧比较
        bb(arr,l+1,right);
    }
}

4.快速排序

//快速排序
/*
具体思路:
	1. 选择要排序数组的左边第一个元素作为基准
	2. 然后从要排序数组的最右边开始进行检索,找比基准数小的,找到后就先停止检索
	3. 然后从要排序数组的最左边开始进行检索,找比基准数大的,找到后就先停止检索	
	4. 将上面两个找到的元素进行交换	
	5. 交换完后,接着使用同样的方式进行检索	
	6. 当左边索引 和 右边索引相等时,停止检索,并且将基准数和相等的这个索引元素进行交换
	7. 然后发现,在相遇的这个位置,左边的元素都比基准数小,右边	的元素都比基准数大			
接下来,接着分别对相遇索引的左边 和 相遇索引的右边 进行同样的快速排序操作!
 */
public class Test01 {
    public static void main(String[] args) {
        int[] arr={33,17,9,88,77,39};  //定义一个数组长度为6,并且赋了值

        bb(arr,0,arr.length-1);  //定义传递的参数和左右下标,传递的参数分别为:数组变量,左侧长度为0,右侧长度为总长度5

        System.out.println(Arrays.toString(arr));  //快速遍历数组
    }

    public static void bb(int[] arr,int left,int right){  //定义一个静态方法,分别接受传过来的参数arr={33,17,9,88,77,39},left:0,right:5
        //如果左侧下标比右侧下标大 直接停止即可
        if (left>right){  //判断最左侧的数是否大于右侧,大于进入判断语句,并返回bb方法,小于就不进入
            return;
        }
        int l=left; //将左侧下标0赋值给l
        int h=right; //将右侧下标5赋值给h
        int base=arr[l]; //指定数组a[0]下标这个数的值33赋值给base

        while(l<h){  //循环的条件,如果左侧长度小于右侧长度,就进入循环,否则不进入
            while (arr[h]>=base&&l<h){ //右侧的值如果大于基数时右侧下标--
                h--;
            }
            //如果出了循环证明在右侧找到了比基数小的数
            if (l<h){
                arr[l]=arr[h]; //把右侧的值赋值给左侧的位置
            }
            //左侧判断的实现 左侧的数字比基数小 这个时候把左侧的下标++
            while (arr[l]<=base&&l<h){
                l++;
            }
            //如果出了while循环证明在左侧找到了比基数大的值
            if (l<h){
                arr[h]=arr[l]; //把左侧的值赋值给右侧
            }
            //如果出现等于情况 我们就把基数直接赋值给指定下标
            if (l>=h){
               arr[l]=base;
            }
        }
        //左侧的比较
        bb(arr, left, l-1);
        //右侧比较
        bb(arr,l+1,right);
    }
}

5.递归

//递归算法
//递归自己调用自己--递归的出现就是代替循环
//递归一定要注意,必须指定可以让程序停止的条件
public class Test01 {
    public static void main(String[] args) {

        int a = aa(6);  //调用静态方法,赋值,并且将返回值6赋值给a
        System.out.println(a);
    }

    public static  int aa(int n){
        int result;
        if (n==1){  //停止条件 如果n等于1,就直接返回1
            result=1;
        }else {
            result=n*aa(n-1); //进行递归运算调用之前每一次结果
        }
        return result; //把结果返回
    }
}

6.二分查找

//二分查找
/*
具体思路:
	折半查找又称为二分查找,这种查找方法需要待查的查找表满足两个条件:
	首先,查找表必须使用顺序存储结构;
	其次,查找表必须按关键字大小有序排列。
 */
public class Test04 {
    public static void main(String[] args) {
        int[] arr ={1,2,3,4,5,6,7,8,9,10};

        int index = getIndex(arr, 0, arr.length - 1, 2); //传参 数组变量 左侧开始下标0 数组的长度9 查询的目标
        System.out.println("目标数字的下标为:"+index);  //输出返回值


    }
    public static int   getIndex(int[] arr,int start,int end,int tag){  //定义一个方法参数分别为数组,左侧开始下标,右侧结束下标,查询的目标
        if (arr==null||arr.length==0){  //判断数组是否为空
            return -1;
        }
        while (start<=end){  //左侧的下标要小于等于右侧的下标

           int mid=(start+end)/2;  //中间的下标等于两侧的索引相加除以2,求出中间变量的下标

           if (tag==arr[mid]){  //查询目标的值等于中间变量索引的值,等于就直接返回
               return mid;  //
           }else if (tag>arr[mid]){  //查询目标的值大于中间变量的值,左侧下标就往中间值右侧+1
               start=mid+1;
           }else {
               end=mid-1;  //最后不满足上面两个条件,右侧下标就往中间值左侧-1
           }
        }
        return -1;  //数组里面没有查询目标的数时,就返回-1
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲸叫我照顾大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值