第三章----数组

数组

Array,多个相同类型数据按一定顺序排列的集合,使用一个名字命名,并通过编号的方式对数据进行统一管理

1. 数组特点

  1. 数组是有序排列的
  2. 数组是引用数据类型变量
  3. 在内存中是一组连续的空间
  4. 数组长度一旦确定就不可修改

2. 一维数组使用

一维数组的声明和初始化
如何调用数组的指定位置的元素
如何获取数组的长度
如何遍历数组
数组元素的默认初始化值
数组的内存解析

  1. 声明 和 初始化

    int[] ids;//声明
    
    //静态初始化
    ids = new int[]{1,2,3,4}
    int[] arr = {1,2,3,4,5}//类型推断
    
    //动态初始化
    String[] names =  new String[5];
    
  2. 调用指定位置元素

    String[] names =  new String[5];
    
    names[0] = "a";
    names[1] = "a";
    names[2] = "a";
    names[3] = "a";
    names[4] = "a";
    
  3. 获取数组长度
    names.length

  4. 遍历数组

    String[] names = new String[]{"a","b","c","d"};
    
    for (int i = 0; i < names.length; i++) {
       System.out.println(names[i]);
    }
    
  5. 数组元素的默认初始化值

    整型:		0
    浮点型:		0.0
    char型:		0'\u0000'
    boolean型:	false
    引用类型:	null
    
  6. 数组的内存解析

3.多维数组的使用

  1. 声明和初始化
    //静态初始化
    int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}}
    int[][] arr1 = {{1,2,3},{4,5},{6,7,8}}//类型推断
    //动态初始化
    String[][] arr2 = new String[3][2];
    //动态初始化
    String[][] arr3 = new String[3][];
    
  2. 获取指定位置数据
    arr1[1][1]
  3. 获取数组长度
    arr.length 
    arr[0].length
    
  4. 遍历二维数组
    for(int i = 0; j < arr.length; i++){
    	for(int j = 0; j < arr[i].length; j++){
    		System.out.print(arr[i][j] + "  ")
    	}
    	System.out.println();
    }
    
  5. 数组元素的默认初始化值
    初始化方式一:int[][] arr = new int[4][3]
    外层元素的初始化值为:地址值
    内存元素的初始化值为:同一维数组初始化情况相同
    
    初始化方式一:int[][] arr = new int[4][]
    外层元素的初始化值为:null
    内层元素的初始化值为:不能调用,否则报错。
    

练习

1.查找类练习
杨辉三角

打印10行杨辉三角

1	
1	1	
1	2	1	
1	3	3	1	
1	4	6	4	1	
1	5	10	10	5	1	
1	6	15	20	15	6	1	
1	7	21	35	35	21	7	1	
1	8	28	56	70	56	28	8	1	
1	9	36	84	126	126	84	36	9	1


 //1.声明二维数组
 int[][] yangHui = new int[10][];
 //2.给数组赋值
 for (int i = 0; i < yangHui.length; i++) {
     yangHui[i] = new int[i + 1];
     yangHui[i][0] = yangHui[i][i] = 1;
     for (int j = 1; j < yangHui[i].length - 1; j++) {
         yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
     }
 }
 //3.遍历二维数组
 for (int i = 0; i < yangHui.length; i++) {
     for (int j = 0; j < yangHui[i].length; j++) {
         System.out.print(yangHui[i][j] + "\t");
     }
     System.out.println();
 }
回形数
2.获取数组元素中的最大,最小,平均值等
最大,最小,和,平均
        int[] arr = new int[10];
        //[10,99]
        //(int)(Math.random() * (99 - 10 + 1) + 10)
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10);
        }
        //最大值
        int maxValue = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (maxValue < arr[i]){
                maxValue = arr[i];
            }
        }
        System.out.println(maxValue);

        //最小值
        int minValue = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (minValue > arr[i]){
                minValue = arr[i];
            }
        }
        System.out.println(minValue);

        //和
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println(sum);


        //平均
        double avg = 0;
        avg = sum* 1.0/arr.length ;
        System.out.println(avg);
3.数组的复制,反转,查找(线性查找,二分法查找)
数组复制
String[] arr1 = new String[]{"JJ","DD","MM","BB","GG","AAA"};

String[] arr2 = new String[arr1.length];
for(int i = 0; i < arr1.length; i++){
	arr2[i] = arr1[i];
}
数组反转
for(int i = 0; i < arr.length / 2; i++){
	String temp = arr[i];
	arr[i] = arr[arr.length - i - 1];
	arr[arr.length - i -1] = temp;
}


for(int i = 0; j = arr.length - 1; i < j; i++,j--){
	String temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}
数组查找
int[] arr = new int[]{0,1,2,3,4,5,6,7,8,9,11};

int dest = 4;
int head = 0;
int end = arr.length - 1;
boolean isFlag = true;
while(head <= end){
	int middle = (head + end)/2;

	if(dest == arr[middle]){
		isFalg = false;
		break;
	}else if(arr[middle] > dest){
		end = middle - 1;
	}else {
		head = middle + 1;
	}
}

if(isFlag){
	System.out.println("not find");
}
4.数组排序

十大内部排序算法

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

冒泡排序
    /**
     * 冒泡排序
     */
    @Test
    public void test4() {
        int[] arr = new int[]{1, 9, 2, 8, 3, 7, 5, 4};

        //冒泡次数
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println( "第" + i + "轮 : " + Arrays.toString(arr));
        }

        System.out.println(Arrays.toString(arr));
    }
插入排序

    /**
     * 插入排序
     * 从后往前插
     */
    @Test
    public void test3() {
        int[] arr = new int[]{19, 122, 23, 139, 41, 43, 124};


        //从第二个数开始向前插入
        for (int i = 1; i < arr.length; i++) {
            int nowdata = arr[i];//记录要插入的数值

            /*
                k = i - 1: 说明k是从 需要插入的目标值前一位,到数组开头
                k >= 0: 循环查找已排好序的数组索引的最前方,最小只到 0 索引
                arr[k] > nowdata : 只要前方比较的值大于目标值就 还没到 目标位置,
             */
            int k = 0;
            for (k = i - 1; k >= 0 && arr[k] > nowdata; k--) {
                arr[k + 1] = arr[k];//为找到目标位置,将数组想目标值移动一格
            }
            arr[k + 1] = nowdata;//将目标值放入到目标位置上
        }

        System.out.println(Arrays.toString(arr));
    }
选择排序
    @Test
    public void test6() {
        int[] arr = new int[]{1, 9, 2, 8, 3, 7, 5, 4};

        //最多 找数组长度减一次
        for (int i = 0; i < arr.length - 1; i ++ ){
            int max_id = i;//第I个数

            for (int j = i + 1; j < arr.length; j++) {
                //找到最大值的索引
                if (arr[j] > arr[max_id]){
                    max_id = j;
                }
            }

            if (max_id != i){
                int temp = arr[i];
                arr[i] = arr[max_id];
                arr[max_id] = temp;
            }
        }

        System.out.println(Arrays.toString(arr));
    }
快排
/**
     * 快速排序
     */
    @Test
    public void test9() {
        int[] arr = {3,4,5,1,23,3,4,5,6,7,2,4,6,5,4234,22,3,457,34,32};
        Quick_sort(arr,0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    public void Quick_sort(int[] arr, int low, int high) {
        if (arr == null || arr.length <= 1) {
            return;//不需要
        }
        if (low < high) {
            int mid = getmid(arr, low, high);
            Quick_sort(arr, low, mid - 1);
            Quick_sort(arr, mid + 1, high);
        }
    }

    public int getmid(int[] arr, int low, int high) {
        int temp = arr[low];//第一个数据
        while (low < high){
            while (low < high && arr[high] >= temp){
                high--;//取出左边的一个大于第一个值的数据
            }
            arr[low] = arr[high];
            while (low < high && arr[low] < temp){
                low++;//取出最右边的一个小于第一个值的数据
            }
            arr[high] = arr[low];//填充
        }
        arr[low] = temp;
        //show();
        return low;
    }
堆排序
    /**
     * 选出最大值
     * arr = [3,1,6,7,8,4,2,9,3,5]
     * <p>
     *                                                                            arr[0] = 3
     * <p>
     *                                                  arr[1] = 1                                          arr[2] = 6
     * <p>
     *                                arr[3] = 7                      arr[4] = 8                  arr[5] = 4               arr[6] = 2
     * <p>
     *                      arr[7] = 9       arr[8] = 3         arr[9] = 5
     * <p>
     *         arr[n]
     * arr[n*2+1]  arr[n*2+2]
     */
    public void findmax(int[] arr) {
        //从数组的最后开始循环,可以看作从堆的堆底开始向上走
        for (int i = arr.length - 1; i > 0; i--) {
//            int parent = (i-1)/2; //取出父节点
            int parent = i / 2; //取出父节点
            int child = i;//记录当前节点
            if (i < arr.length - 1 && arr[i] < arr[i + 1]) {
                child += 1;
            }
            if (arr[child] > arr[parent]) {
                int temp = arr[child];
                arr[child] = arr[parent];
                arr[parent] = temp;
            }
        }
    }

    public void myfindmax(int[] arr) {
        //从数组的最后开始循环,可以看作从堆的堆底开始向上走
        for (int i = arr.length - 1; i > 0; i--) {
            int parent = (i-1)/2; //计算出当前节点父节点
            int child = i; //记录当前节点

            //判断当前节点是否为左节点:左节点才比较两子节点大小,再比较父子大小
            if (2*parent + 1 == child){
                //如果不是最后一点,比较两子节点,得到最大子节点索引
                if (i < arr.length - 1 && arr[i] < arr[i + 1]) {
                    child += 1;
                }
                if (arr[child] > arr[parent]) {
                    int temp = arr[child];
                    arr[child] = arr[parent];
                    arr[parent] = temp;
                }
            }
        }
    }

    @Test
    public void test7() {
        int[] arr = {3, 1, 6, 7, 8, 4, 2, 9, 3, 5};
        myfindmax(arr);
//        findmax(arr);

        System.out.println(Arrays.toString(arr));
    }


    @Test
    public void test8() {
        int[] arr = {3, 1, 6, 7, 8, 4, 2, 9, 3, 5};
        if (arr == null || arr.length <= 1) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int[] newarr = Arrays.copyOfRange(arr, i, arr.length);
            findmax(newarr);
            for (int j = 0; j < newarr.length; j++) {
                arr[i + j] = newarr[j];
            }
        }
        System.out.println(Arrays.toString(arr));
    }
二分查找插入
/**
 * 可以一边读取文件,一边插入,(找到位置时可以使用二分查找) ---- 二分插入排序法
 */
public class BinsearchInsetSort extends Sort {


    public BinsearchInsetSort(int[] data) {
        super(data);
    }

    /**
     * 将数据锁定在某一段之间
     */
    public void goSort(){
        //第一个数不用插,从第二个数开始插入
        for(int i = 1; i < data.length;i++){
            //插入条件
            if (data[i] < data[i - 1]){
                int temp = data[i];//保存要插入的值,为数据移动藤出空间
                //二分查找
                int low = 0;        //二分查找的下限
                int height = i -1;  //二分查找的上限
                while (low <= height) {//左右夹逼
                    int mid = (low + height) / 2;//取中间值

                    //比较中间值与插入值大小,重新界定查找范围,最终low的位置是插入位置
                    if (data[mid] < temp) {
                        low = mid + 1;
                    } else {
                        height = mid - 1;
                    }
                }
                //循环完毕后该插入的坐标是在low的位置上
                //向后移动数组
                for (int j = i; j > low; j--){
                    data[j] = data[j - 1];
                }
                data[low] = temp;

            }
        }
    }

    public static void main(String[] args) {
        int[] data = {1,20,3,1,2,3,5,98,43,45,7,5};
//        Sort st = new BinsearchInsetSort(data);
        Sort st = new MergeSort(data);
        st.show();
        st.goSort();//对整个数组排序
        st.show();
    }
}
归并排序
public class Sort {

   public  int[] data;

    public Sort(int[] data) {
        this.data = data;
    }

    public void goSort(){
        Arrays.sort(data);
    }

    public void show(){//显示
        for (int i : data){
            System.out.print(i + "\t");
        }
        System.out.println("\n");
    }

    public void show(int left,int right){//显示
        while (left <= right){
            System.out.print(this.data[left++] + "\t");
        }
        System.out.println("\n");
    }
}


**
 * O(nlog2n)
 */
public class MergeSort extends Sort {
    public MergeSort(int[] data) {
        super(data);
    }

    @Override
    public void goSort() {
        sortit(0, data.length - 1 );
    }
    void sortit(int left,int right){
        if (left >= right){//一个元素终止
            return;
        }

        int center = ( left + right )/2;//切半
        sortit(left,center);//左半
        sortit(center + 1,right);//右半

        //递归放在最下面的是逆序
        merge(left,center,right);

//        this.show();
    }
    void merge(int left,int center,int right){
        int oldleft = left;
        int oldright = right;
        System.out.print("归并前:");
        show(oldleft,oldright);

        //临时数组
        int[] temparr = new int[data.length];//归并



        int mid = center + 1;   //右边数组的第一个元素
        int third = left;       //缓存数组的 数组索引
        int temp = left;        //左边数组的索引

        //将左右两个的数组 第一个最小的数组打印过来
        while (left <= center && mid <= right){
            if (data[left] <= data[mid]){
                temparr[third++] = data[left++];
            } else {
                temparr[third++] = data[mid++];
            }
        }
        //将剩余数组归并,接上尾部的一段
        while (mid <= right){
            temparr[third++] = data[mid++];
        }
        while (left <= center){
            temparr[third++] = data[left++];
        }

        //归并后的数组拷贝到原来的数组
        while (temp <= right){
            data[temp] = temparr[temp++];
        }

        System.out.print("归并后:");
        show(oldleft,oldright);
    }
}





    public static void main(String[] args) {
        int[] data = {1,20,3,1,2,3,5,98,43,45,7,5};
        Sort st = new MergeSort(data);
        st.show();
        st.goSort();//对整个数组排序
        st.show();
    }
桶排序
/**
 * 桶排序
 */
public class BuckerSortTest {

    public static void bucketsort(int[] ages,int min,int max){
        int [] buffer = new int[max - min + 1];

        for (int i = 0; i < ages.length;i++){
            buffer[ages[i]]++;
        }

        for (int i = 0,j = 0; i <= max; i++){//i:循环桶, j:循环ages
            while (buffer[i]-->0){
                ages[j++] = i;
            }
        }
    }



    public static void main(String[] args) {
        //创建随机数
        int[] ages = new int[1000];
        for (int i = 0; i < 1000; i++) {
            ages[i] = (int) (Math.random() * (100 - 0 + 1));
        }

        for (int age : ages){
            System.out.print(age + "\t");
        }
        System.out.print("\n");


        bucketsort(ages,0,100);


        for (int age : ages){
            System.out.print(age + "\t");
        }
        System.out.print("\n");
    }
}

基数排序
public class RadixSortTest {
    public static void main(String[] args) {
        //创建随机数
        int[] ages = new int[1000];
        for (int i = 0; i < 1000; i++) {
            ages[i] = (int) (Math.random() * (9999 - 0 + 1));
        }

        show(ages);
        radixsort(ages);
        show(ages);
    }


    public static void radixsort(int[] data) {
        int exp;//位数
        int max = getmax(data);

        //从个位开始,指数排序
        for (exp = 1; max / exp > 0; exp *= 10) {
            //按照位数处理
            countsort(data, exp);
        }
    }

    public static void countsort(int[] data, int exp) {
        int[] output = new int[data.length];//备份
        int[] buckets = new int[10];//数据出现的次数保存  0-9

        
        for (int i = 0; i < data.length; i++) {
            buckets[(data[i] / exp) % 10]++;
        }

        //出现的位置
        for (int i = 1; i < 10; i++) {
            buckets[i] += buckets[i - 1];
        }


        //数据存储到临时数组
        for (int i = data.length - 1; i >= 0; i--) {
            output[buckets[(data[i] / exp) % 10] - 1] = data[i];
            buckets[(data[i] / exp) % 10]--;
        }

        //赋值,排序的值给data: 数据拷贝
        for (int i = data.length - 1; i >= 0; i--) {
            data[i] = output[i];
        }
        output = null;
        buckets = null;
    }

    //控制台打印
    public static void show(int[] data) {
        for (int i : data) {
            System.out.print(i + "\t");
        }
        System.out.print("\n");
    }

    //获取最大值
    public static int getmax(int[] data) {
        int max = data[0];
        for (int i = 1; i < data.length; i++) {
            if (data[i] > max) {
                max = data[i];
            }
        }
        return max;
    }


}

Arrays 工具类

  • equals()
  • copyOf()
  • toString()
  • fill()
  • binarySearch()
  • sort()
    /**
     * equals
     * 需要数据类型相同,数组中元素顺序也相同
     *
     * copyOf : 数组拷贝
     *
     * toString :将数组转为打印字符串
     *
     * fill : 填充方法
     *
     * binarySearch() : 二分查找法
     */
    @Test
    public void test1(){
        int[] a1 = new int[]{1,2,3,4,5};
        int[] a2 = new int[]{1,2,3,4,5};
        int[] a3 = new int[]{1,2,3,5,4};
        double[] a4 = new double[]{1,2,3,4,5};
        System.out.println(Arrays.equals(a1,a2));
        System.out.println(Arrays.equals(a1,a3));
//        System.out.println(Arrays.equals(a1,a4));

        int[] b = Arrays.copyOf(a1, 5);
        int[] b2 = Arrays.copyOfRange(a1, 0, 2);
        System.out.println(Arrays.toString(b));
        System.out.println(Arrays.toString(b2));

        int[] c = new int[10];
        int[] c2 = new int[10];
        Arrays.fill(c,10);
        Arrays.fill(c2,1,3,100);
        System.out.println(Arrays.toString(c));
        System.out.println(Arrays.toString(c2));


        int i = Arrays.binarySearch(a3, 5);
        System.out.println(i);
    }
  • parallelSort
  • parallelPrefix
  • parallelSetAll
    /**
     * parallelSort : 并发排序
     */
    @Test
    public void test2(){
        int[] arr = new int[64];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * (100 - 0 + 1));
        }
        System.out.println(Arrays.toString(arr));
        Arrays.parallelSort(arr);//并发排序,多线程排序
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 并发计算 :
     *
     * parallelPrefix
     *
     * parallelSetAll
     *
     */
    @Test
    public void test3(){

        int[] arr = new int[64];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * (100 - 0 + 1));
        }
        System.out.println(Arrays.toString(arr));

        int[] arr2 = Arrays.copyOf(arr, arr.length);
        int[] arr3 = Arrays.copyOf(arr, arr.length);
        Arrays.parallelSort(arr2);
        System.out.println(Arrays.toString(arr2));


        //并发相邻计算
        Arrays.parallelPrefix(arr, new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        });
        System.out.println(Arrays.toString(arr));


        Arrays.parallelSetAll(arr3, new IntUnaryOperator() {
            @Override
            public int applyAsInt(int index) {
                return arr3[index] + 2;
            }
        });
        System.out.println(Arrays.toString(arr3));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

悠闲的线程池

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

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

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

打赏作者

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

抵扣说明:

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

余额充值