韩顺平java05(数组、排序和查找)

数组、排序和查找

一维数组

三种初始化方式:

  1. 动态初始化(1)

  数据类型 [] 数组名=new  数据类型  [大小];

int   [] num    =new   int   [10];

可以 使用数组名.length获取数组长度


Scanner sc = new Scanner(System.in);
for (int i = 0; i < weight.length; i++) {
    weight[i] = sc.nextDouble();
}
for (int i = 0; i < 5; i++) {
    System.out.println(weight[i]);
}
  1. 动态初始化(2)

  数据类型 [] 数组名;

int    [] nums;
nums = new int[5];
  1. 静态初始化

数据类型 [] 数组名={元素值 , 元素值 , ... };

int[] arrays = {1, 2, 3, 4, 5};
  • 注意细节:

 这里主要注意数组元素的类型要一致以及数组下标是否越界

小练习:

1.存贮字母表并打印

//字母表
        double [] alpha = new double[26];
        char a = 'A';
        for (int i = 0; i < alpha.length; i++) {
            alpha[i] =a;
            a++;
            System.out.print((char) alpha[i] + "\t");
        }

老师改进:

double [] alpha = new double[26];
        for (int i = 0; i < alpha.length; i++) {
            alpha[i] ='A' + i;
            System.out.print((char) alpha[i] + "\t");
        }

2.找出数组元素最大值和对应下标

double [] num = {5.6 , 56, 88 , -8 ,3.14, 4678 };
        double max = 0;
        int maxIndex = 0;

        for (int i = 0; i < num.length ; i++){
            if (num[i] > max){
                max = num[i];
                maxIndex = i;

            }
        }
        System.out.println("max:" + max +"index:" + maxIndex);

老师版:

double [] num = {5.6 , 56, 88 , -8 ,3.14, 4678 };
        double max = num[0]; //将第一个元素假定为最大值
        int maxIndex = 0;
        for (int i = 1; i < num.length ; i++){
//然后从第二个元素开始遍历
if (num[i] > max){ max = num[i]; maxIndex = i; } } System.out.println("max:" + max +"index:" + maxIndex);

数组赋值机制

  • 基本类型数据的赋值方式为——值拷贝
int n1 = 10;
        int n2 = n1;
        n2 = 20;
        System.out.println("n1:" + n1); //n1:10
        System.out.println("n2:" + n2); //n2:20

可以看到这里n2的变化并不会影响到n1的值

int n1 = 10; ->开辟一块空间给n1;

 int n2 = n1; - > 将n1的值——10拷贝给n2; 后边的80也是一样,所以对n1没有影响。

  • 而数组默认情况下是引用传递,赋的值是地址
int [] array1 = {1,2,3};
        int [] array2 = array1;

        array1[0] = 10;
        
        for (int i = 0;i < array2.length;i++){
            System.out.println(array2[i]);  //10 2 3
        }

这里我们先把array2的地址指向array1,然后改变了array第一个元素的值,发现array的第一个元素也随之变化了,因为数组在jvm对应的是堆,指向的是地址。所以改变array1【0】的值,array2【0】也随之变化

数组拷贝

注意:内存里分配一块空间一定会对应一个地址

因为每开辟一块新的空间都会对应一块新的地址,所以这里新的数组arr再怎么变化也不会影响到arr1了。 

 数组反转

1.找规律元素交换

int [] num = {1,2,3,4,5,6};
        for ( int i = 0;i < num.length/2;i++){
            int temp = num[i];
            num[i]=num[num.length-1-i];
            num[num.length-1-i]=temp;
        }
        for (int i = 0;i<num.length;i++){
            System.out.println(num[i]);
        }

2.逆序赋值再指向新数组

int [] num = {1,2,3,4,5,6};
        int [] num2 = new int[num.length];
        for ( int i = num.length-1;i >= 0;i--){
            num2[i]=num[num.length-1-i];
        }

        num=num2;//将num指向num2

        for (int i = 0;i<num.length;i++){
            System.out.println(num[i]);
        }

数组扩容

  •  小练习:用户输入(y/n)决定是否继续添加数据
//数组扩容
        int [] num = {1,2,3,4,5,6};
        System.out.print("原数组:");
        for (int i = 0;i<num.length;i++){
            System.out.print(num[i]+"\t");
        }
        System.out.println();
        Scanner sc = new Scanner(System.in);


        while (true){

            System.out.println("是否继续添加数据(y/n)");
            char c = sc.next().charAt(0);
            if (c=='n')
                break;

            int [] num2 = new int[num.length + 1];
            for ( int i = 0;i <= num.length-1;i++){
                num2[i]=num[i];//数组拷贝
            }
            System.out.println("请输入新数据:");
            int newarr = sc.nextInt();
            num2[num.length]= newarr; //将输入的新数据添加到新数组的最后一个元素的位置
            num = num2;//指向新数组
        }
        System.out.println("添加结束");
        System.out.print("新数组:");
        for (int i = 0;i<num.length;i++){
            System.out.print(num[i] + "\t");
        }

数组缩减

//数组缩减
        int [] num = {1,2,3,4,5};
        System.out.print("原数组:");
        for (int i = 0;i<num.length;i++){
            System.out.print(num[i]+"\t");
        }
        System.out.println();
        Scanner sc = new Scanner(System.in);
        
        while (true){

            System.out.println("是否继续删除数据(y/n)");
            char c = sc.next().charAt(0);
            if (c=='n' ) //如果选择n则退出循环
            {
                break;
            }
            int [] num2 = new int[num.length - 1]; //定义一个长度为圆原数组-1的新数组

            for ( int i = 0;i <= num.length-2;i++){
//                接收0-length-2的数据
                num2[i]=num[i];
            }
            num = num2;
            if (num2.length == 1){
                //赋值完毕后再判断新数组长度是否为1
                System.out.println("无法继续缩减!");
                break;
            }
        }
      System.out.println("删除结束");
        System.out.print("新数组:");
        for (int i = 0;i<num.length;i++){
            System.out.print(num[i] + "\t");
        }

二维数组

初始化方式

  1. 动态初始化(1)

  数据类型 [] []数组名=     new    数据类型  [大小][大小];

int   [] [] num    =new   int   [2][3];
int [][] array = new int[2][3] ;
        array[1][1] = 1;
        for (int i = 0; i<array.length;i++){//外循环次数为二维数组的行数 即array.length-1次
            for (int j =0;j<array[i].length;j++){//内循环次数为一维数组的长度 即array[i].length-1次
                System.out.print(array[i][j] + "\t");
            }
            System.out.println();
        }
    }

踩坑:一开始条件判定写成了i<array.length - 1 ,忽略了i是从0开始的

        2.动态初始化(2)

    3. 动态初始化(列元素个数不确定)

 4.静态初始化

 只有靠近数组名的那一维在定义时可以空着

内存中的存储方式:

 二维数组中存储的是两个一维数组的地址,然后一维数组的地址再指向真正的数据。

  • 二维数组注意细节

  • 练习

排序简介

排序分类  :

  • 内部排序:

内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。

有:

1.插入排序(直接插入排序);2.快速排序;

3.选择排序(简单选择排序); 4.归并排序 ;

5.冒泡排序; 6.希尔排序(对直接插入排序方法的改进)

7.堆排序; 8.基数排序;

  • 外部排序:

外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。(包括合并排序法和直接合并排序法)

冒泡排序(bubble sorting)

 int [] array = {56  , 63 , 54 , 2, 89};
        System.out.println("排序前:");

        for(int  i = 0; i< array.length;i++){
            System.out.print(array[i]+"\t");
        }
        System.out.println();
        for(int  i = 0; i< array.length-1;i++){ //length-1是因为如果所有都比完了剩下最后一个就不用比了
            for (int j =0 ; j<array.length-1-i;j++){ //这里一开始写的是j<array.length-1 看了老师的发现可以再-i 因为比较次数依次减少
                if (array[j]<array[j+1]){
                    //如果后面的大 就和前面的交换
                    int temp = array[j+1];
                    array[j+1] =array[j];
                    array[j] = temp;
                }
            }
        }
        System.out.println("排序后:");
        for(int  i = 0; i< array.length;i++){
            System.out.print(array[i]+"\t");
        }

其他排序后面的数据结构再实现,这里先不继续了 

查找

在java中常用的数组有两种——顺序查找和二分查找

这里我们先实现以下顺序查找的代码

查找数组中是否含有某个数,并输出下标。

int [] array = {1,2,3,4,5};
        Scanner sc = new Scanner( System.in);
        System.out.println("请输入要查询的数字:");
        int num = sc.nextInt();
        int index = 0;
        
        for (int i = 0;i<array.length;i++){

            if (num == array[i]){
                index = i;
                System.out.println("找到了下标为:" + index);
            }else{
                System.out.println("没找到");
            }
        }
        

如果先这样写,就会导致不管有没有都会在不相等的时候一直走else输出“没找到”

这里我们引入一个加flag的思想,先定义一个标记,如果找到了标记改变,如果没找到判断标记没有变化的时候输出“没找到”,之前的找质数也是这个道理。

老师改进:

int [] array = {1,2,3,4,5};
        Scanner sc = new Scanner( System.in);
        System.out.println("请输入要查询的数字:");
        int num = sc.nextInt();
        int index = 0;
        boolean flag = false;
        for (int i = 0;i<array.length;i++){

            if (num == array[i]){
                index = i;
                System.out.println("找到了下标为:" + index);
                flag = true;
                break;
            }
        }
        if (flag == false){
            System.out.println("没找到");
        }

这个思想666

本章练习

1.

 D选项这样写是可以的但是不能在【】里加数字,让编译器判断有几个元素,E属于画蛇添足

2.

输出blue 知识点:boolean类型数组默认值为false

3.在升序数组中插入一个值使得新数组依然是升序数组

//数组插入数据,并保持 插入后数组保持升序
int [] num = {1,6,99};
        System.out.print("原数组:");
        for (int i = 0;i<num.length;i++){
            System.out.print(num[i]+"\t");
        }
        System.out.println();
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入新数据:");
        int newNum = sc.nextInt();
        int index = -1;

        for (int i = 0; i< num.length;i++){
            if (newNum <= num[i]){
                index = i;
                break;
            }
        }
        if (index ==-1)index=num.length;
        int [] newarr = new int[num.length+1];

        for (int i = 0,j=0;i < newarr.length;i++){
            if (i!= index){                    // 表示可以直接拷贝元素
                newarr[i]=num[j];
                j++;
            }else{
//                这里如果走else则j就不++了,所以在newNum插入之后i比j大1   666
                newarr[i]=newNum;
            }
        }
        num=newarr;                    //指向新数组,原数组销毁
        System.out.print("新数组:");
        for (int i = 0;i<num.length;i++){
            System.out.print(num[i]+"\t");
        }

5.

 

 

int [] array = new int[10];
        int sum = 0;
        int max = 0;
        int index = 0;
        boolean flag = true;
        for (int i=0;i<array.length;i++){
            array[i]=(int) (Math.random()*100+1);
            sum += array[i];
            if (max < array[i]){
                max = array[i];
                index = i;
            }
        }

        System.out.println("原数组:");
        for (int i=0;i<array.length;i++){
            System.out.print(array[i] +"\t");
        }
        System.out.println();
        System.out.println("原数组和为:"+sum+"平均数为:"+sum/10+"最大值为:"+max + "最大值下标"+ index);
        System.out.println("原数组倒序:");
        int [] num2 = new int[array.length];
        for ( int i = array.length-1;i >= 0;i--){
            num2[i]=array[array.length-1-i];
        }
        array=num2;//将num指向num2
        for (int i=0;i<array.length;i++){
            if (array[i]==8)flag=false;
            System.out.print(array[i] +"\t");
        }
        if (flag) System.out.println("数组不含8");
posted @ 2021-12-07 02:06  紫英626  阅读(113)  评论(0编辑  收藏  举报

紫英