七 数组中涉及的常见算法(排序和查找算法)

目录

01 数组元素基本操作

02 数组的复制

03 数组的反转

04 数组的查找

4.1 线性查找

 4.2 二分查找

05 排序算法

5.1 概述

5.2 十种排序算法

5.2.1 冒泡排序

5.2.2 快速排序

 06 Arrays 工具类的使用

 07 数组异常


 

01 数组元素基本操作

package Matrix;
/*
定义一个int 型的一维数组,包含 10 个元素,分别赋一些随机整数,
然后求出所有元素的最大值, 最小值,和值, 平均值, 并输出 出来 。
要求:所有随机数都是两位数。
 */
public class ArrayTest3 {
    public static void main(String[] args){
        int[] arr = new int[10];
        int maxNum = 0;
        int minNum = 100;
        int sum = 0;
        int averNum = 0;
        for(int i = 0; i < arr.length; i++){
            // 赋值
            arr[i] =  (int)(Math.random() * 90 + 10);
            sum += arr[i];
            if(maxNum < arr[i]){
                maxNum = arr[i];
            }
            if(minNum > arr[i]){
                minNum = arr[i];
            }
            System.out.println(arr[i] + " ");
        }
        averNum = sum / 10;
        System.out.println("最大值为" + maxNum);
        System.out.println("最小值为" + minNum);
        System.out.println("平均值为" + averNum);
        System.out.println("和值为" + sum);
    }
}

02 数组的复制

数组赋值

  •  直接相等,是赋值地址,会同时改变
/*
创建一个 名为 ArrayTest 的 类,在 main() 方法中声明 array1 和 array2 两 个 变量,
他们 是 int 类型的数组。
使用大括号 {}{},把 array1 初始化为 8 个素数: 2,3,5,7,11,13,17,19 。
显示 array1 的内容。
赋值 array2 变量等于 array1 ,修改 array2 中的偶索引元素,使其等于索引值
如 array[0]=0,array[2]=2) 。打印出 array1
 */
public class FuZhiArray {
    public static void main(String[] args){
        int[] array1 = new int[]{2,3,5,7,11,13,17,19};
        int[] array2;                     // 这里来初始化不能用new 否则后面无法编译
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        System.out.println();

            // 赋值arr2 = arr1
            array2 = array1;
        for (int i = 0; i < array2.length; i++){
            if (i % 2 == 0){
                array2[i] = i;
            }
            System.out.print(array1[i] + "\t");
        }

    }
}

实现数组的复制

 // 复制arr2 = arr1
        int[] array2 = new int[array1.length];
        for (int i = 0; i < array2.length; i++){
            array2[i] = array1[i];

03 数组的反转

public class FuZhiArray {
    public static void main(String[] args){
        int[] array1 = new int[]{2,3,5,7,11,13,17,19};
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        System.out.println();

        // 数组反转方法一
       //  for (int i = 0; i < array1.length / 2; i++){
          //   int temp = array1[i];
           //  array1[i] = array1[array1.length-i-1];
           // array1[array1.length - i - 1] = temp;
       // }

        // 方法二
        for( int i = 0, j= array1.length-1; i < j; i++,j--){
            int temp = array1[i];
            array1[i] = array1[j];
            array1[j] = temp;
        }

        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}

04 数组的查找

4.1 线性查找

public class FuZhiArray {
    public static void main(String[] args){
        int[] array1 = new int[]{2,3,5,7,11,13,17,19};
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        System.out.println();

        // 查找
        int num = 5;             // 设置要找的数
        boolean flag = true;    // 如果没找到的标识符
        for(int i= 0; i < array1.length; i++){
            if(num == array1[i]){
                System.out.println("找到了");
                flag = false;
                break;
            }
            }
        if(flag){     // 没改过,说明没找到
            System.out.println("没找到");
        }
    }
}

 4.2 二分查找

public class FuZhiArray {
    public static void main(String[] args){
        int[] array1 = new int[]{2,3,5,7,11,13,17,19};
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        System.out.println();

  
        // 二分查找: 所查找的数组必须有序
        int[] array2 = new int[]{-2,3,5,7,11,13,17,109};
        int num2 = 5;
        int head = 0;  // 初始索引
        int end = array2.length -1; // 末索引
        boolean isFlag = true;   //如果没找到的标识符

        while(head <= end){
            int middle = (head + end) / 2;
            if (num2 == array2[middle]){
                System.out.println("所查找数值的索引为" + middle);
                isFlag = false;
                break;
            }else if(num2 > array2[middle]){
                head = middle + 1;
            }else{
                end = middle - 1;
            }
        }

        if(isFlag){
            System.out.println("没找到");
        }
    }
}

05 排序算法

5.1 概述

  • 排序:假设含有 n 个记录的序列为{R1,R2,…,Rn},其相应的关键字序列为{K1 ,K2,…,Kn}。将这些记录重新排序为{Ri1,Ri2,…,Rin},使得相应的关键字值满足条 Ki1<=Ki2<=…<=Kin,这样的一种操作称为排序。
  • 通常来说,排序的目的是快速查找。

衡量排序算法的优劣:

  • 时间复杂度:分析关键字的比较次数和记录的移动次数
  • 空间复杂度:分析排序算法中需要多少辅助内存
  • 稳定性:若两个记录 A 和 B 的关键字值相等,但排序后 A、B 的先后次序保持不变,则称这种排序算法是稳定的。

排序算法分类:内部排序和外部排序。

  • 内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。
  • 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
     

5.2 十种排序算法

  • 选择排序
    • 直接选择排序、堆排序
  • 交换排序
    • 冒泡排序、快速排序
  • 插入排序
    • 直接插入排序、折半插入排序、Shell 排序
  • 归并排序
  • 桶式排序
  • 基数排序

算法特点

输入(Input)有 0 个或多个输入数据,这些输入必须有清楚的描述和定义
输出(Output)至少有 1 个或多个输出结果,不可以没有输出结果
有穷性(有限性,Finiteness)算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
确定性(明确性,Definiteness)算法中的每一步都有确定的含义,不会出现二义性
可行性(有效性,Effectiveness

算法的每一步都是清楚且可行的,能让用户用纸笔计算而求出答案  

5.2.1 冒泡排序

public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = new int[] {1,2,-34,5,3,4,2,1,6,78,-9};
        // 冒泡排序
        for(int i = 0; i < arr.length - 1; i++){   // i 控制外部排序次数,每个数都要进行排序
            for(int j = 0; j < arr.length - 1 - i; j++){  // j 控制欸一轮的内部排序,即将最大数排到最后一个
                if(arr[j] > arr[j+1]){    // 保证索引能指到最后一个数
                    int temp = arr[j];    // 前面数大于后面数,则交换两个数
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        for (int i = 0; i < arr.length; i++){
            System.out.print(arr[i] + " ");
        }
    }
}

5.2.2 快速排序

排序思想


  • 从数列中挑出一个元素,称为"基准"(pivot)
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。(分而治之)
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

快速排序 java实现

public class QuickSort {
    private static void swap(int[] data, int i, int j){ // 方法的定义,交换索引为i和j两个数值
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
    private static void subSort(int[] data, int start, int end){  //  定义排序方法
        if(start < end){
            // 定义三个指针
            int base = data[start];  // 基准值
            int low = start;
            int high = end + 1;

            while(true){
                while(low < end && data[++low] <= base)  // 前++ 先运算后取值
                    ;

                    // 这里是一个循环,调整low指针位置,直到arr[low] > base
                    // 同理,调整 high指针位置,直到arr[high] < base

                while(high > start && data[--high] >= base)
                    ;

                    // 经过循环的调整,交换两个数值

                if(low < high){    // 只有low还在 high左边时,交换数值
                    swap(data, low, high);

                }else{     // 否则退出
                    break;
                }
            }

            swap(data,start,high);    // 交换基准值和high的指针值,保证基准值左侧比基准值小

            subSort(data, start, high - 1); // 递归调用左侧子列
            subSort(data, high + 1, end); // 递归调用右侧子列
        }
    }

    public static  void quickSort(int[] data){
        subSort(data, 0, data.length - 1);
    }
// 排序样例
    public static void main(String[] args){
        int[] data = new int[]{9, 1,2,5,7,-23,3,-5,98};
        System.out.println("排序之前:" + java.util.Arrays.toString(data));
        quickSort(data);
        System.out.println("排序之后:" + java.util.Arrays.toString(data));
    }

}

 06 Arrays 工具类的使用

java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。

/*
操作数组工具类
boolean equals(int[] a,int[] b):判断两个数组是否相等。
String toString(int[] a) : 输出数组信息。
void fill(int[] a,int val) : 将指定值填充到数组之中。
 */
import java.util.Arrays;
/*
 * java.util.Arrays:作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
 */
public class ArraysTest {
    public static void main(String[] args) {

        //1.boolean equals(int[] a,int[] b)判断两个数组是否相等。
        int[] arr1 = new int[]{1,2,3,4};
        int[] arr2 = new int[]{1,2,9,3};
        boolean isEquals = Arrays.equals(arr1, arr2);
        System.out.println(isEquals);

        //2.String toString(int[] a)输出数组信息。
        System.out.println(Arrays.toString(arr1));

        //3.void fill(int[] a,int val)将指定值填充到数组之中:全部替换
        Arrays.fill(arr1, 10);
        System.out.println(Arrays.toString(arr1));

        //4.void sort(int[] a)对数组进行排序。
        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2));

        //5.int binarySearch(int[] a,int key)对排序后的数组进行二分法检索指定的值。
        int[] arr3 = new int[]{-43,32,76,92,165,185,271,342};
        int index = Arrays.binarySearch(arr3, 210);
        if(index >= 0){
            System.out.println(index);
        }else{
            System.err.println("未找到。");
        }
    }
}

 07 数组异常

public class ArrayExceptionTest {
    /*
     * 数组中的常见异常:
     * 1.数组角标越界的异常:ArrayIndexOutOfBoundsException
     *
     * 2.空指针异常:NullPointerException
     *
     */
        public static void main(String[] args) {

            //1.数组角标越界的异常:ArrayIndexOutOfBoundsException
            int[] arr = new int[]{1,2,3,4,5,6};

            //错误1:
//		for(int i = 0;i <= arr.length;i++){  角标越界
//			System.out.println(arr[i]);
//		}

            //错误2:
//		System.out.println(arr[-2]);

            //错误3 // 一旦出现错误,剩下程序不再执行
//		System.out.println("hello");

            //2.空指针异常:NullPointerException
            //情况一:
//		int[] arr2= new int[]{1,2,3};
//		arr2 = null;    // 指针地址改成空的了
//		System.out.println(arr2[0]);
            //情况二:
//		int[][] arr2 = new int[4][];
//		System.out.println(arr2[0][0]);

            //情况三:
//		String[] arr3 = new String[]{"AA","QQ","YY","XX","TT","KK"};
//		arr3[0] = null;
//		System.out.println(arr3[0].toString());
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值