数组排序 及 二维数组的拷贝

多维数组

 java 支持两种数据类型的多维数组。第一种是矩形数组,也称等长数组。在二维矩形数组中,每一行有相同的列数。例:int[][] A = new int[4][2];
java 支持的第二种多维数组是交错数组,即所谓的正交数组、变长数组、锯齿形数组。在二维交错数组中,每一行可以有不同的列数。
 在多维数组中,比较常用的是二维数组。多维数组的声明、实例化和初始化与一维数组的声明、实例化和初始化相类似。声明多维数组时,用[]对表示维数。两个[]对表示二维数组,3个[]对表示三维数组,以此类推。
 基本数据类型的数组未初始化的值均为 0 , 对象数组 :初始化为null , Boolean:初始化默认为false,字符串:/u0000。

  • 举例:
package com.k;
import java.util.Arrays;
public class Yichang {
public static void  main(String[] args){
        int[][] array = {{1, 2, 3},{4, 5, 6}};
        int[][] brray = new int[2][3];
        int[][] arr1 = new int[2][3]; //声明并创建一个二维整型数组(2行3列)
        int[][] arr2 = {{1,2,3},{4,5,6}}; //声明并初始化一个二维整型数组(2行3列,6个元素)
        int[][] arr3 = new int[][]{{1,2,3},{4,5,6}}; //声明创建并初始化
        int[][] arr4 = new int[3][];
        arr4[0] = new int[2];
        arr4[1] = new int[4];
        arr4[2] = new int[5];     // 不规则数组
       System.out.println(Arrays.deepToString(brray));
       System.out.println(Arrays.deepToString(arr1));
       System.out.println(Arrays.deepToString(arr2));
       System.out.println(Arrays.deepToString(arr3));
       System.out.println(Arrays.deepToString(arr4));
    }
}
[[0, 0, 0], [0, 0, 0]]
[[0, 0, 0], [0, 0, 0]]
[[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6]]
[[0, 0], [0, 0, 0, 0], [0, 0, 0, 0, 0]]

二维数组的拷贝

 二维数组的拷贝和一维数组的拷贝类似,同样有四种,分别是for循环拷贝,Object.clone(),System.arraycopy(),Arrays.copyOf() 四种拷贝方法。下面是代码示例:

  • for循环拷贝(浅拷贝)
package com.k;
import java.util.Arrays;
public class Yichang {
 public static void  main(String[] args){
        int[][] array = {{1, 2, 3},{4, 5, 6}};
        int[][] brray = new int[2][3];
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                brray[i][j] = array[i][j];
            }
        }
        System.out.println(Arrays.deepToString(brray));
    }
}
[[1, 2, 3], [4, 5, 6]]
class TestArray2 {
    private int val;
    public void setVal(int val) {
        this.val = val;
    }
    public int getVal() {
        return this.val;
    }
}

public class Yichang {
  public static void main(String[] args) {
        TestArray2[][] testArray2 = new TestArray2[2][2];
        testArray2[0][0] = new TestArray2();
        testArray2[0][1] = new TestArray2();
        testArray2[1][0] = new TestArray2();
        testArray2[1][1] = new TestArray2();
        TestArray2[][] testArray3 = new TestArray2[2][2];
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
                testArray3[i][j] = testArray2[i][j];
            }
        }
        System.out.println("拷贝完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
                System.out.print(testArray2[i][j].getVal() + " ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3.length; j++) {
                System.out.print(testArray3[i][j].getVal() + " ");
            }
        }
        System.out.println();
        testArray2[0][0].setVal(100);
        System.out.println("修改完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2[i].length; j++) {
                System.out.print(testArray2[i][j].getVal()+" ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3[i].length; j++) {
                System.out.print(testArray3[i][j].getVal()+" ");
            }
        }
        System.out.println();
    }
  }
拷贝完成
0 0 0 0 
0 0 0 0 
修改完成
100 0 0 0 
100 0 0 0 
  • ** Arrays.deepToString() 方法是多维数组以字符串形式输出。**
  • Object.clone()
class TestArray2 {
    private int val;
    public void setVal(int val) {
        this.val = val;
    }
    public int getVal() {
        return this.val;
    }
}

public class Yichang {
  public static void main(String[] args) {
        TestArray2[][] testArray2 = new TestArray2[2][2];
        testArray2[0][0] = new TestArray2();
        testArray2[0][1] = new TestArray2();
        testArray2[1][0] = new TestArray2();
        testArray2[1][1] = new TestArray2();
        TestArray2[][] testArray3 = new TestArray2[2][2];
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
               testArray3[i] = testArray2[i].clone();
            }
        }
        System.out.println("拷贝完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
                System.out.print(testArray2[i][j].getVal() + " ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3.length; j++) {
                System.out.print(testArray3[i][j].getVal() + " ");
            }
        }
        System.out.println();
        testArray2[0][0].setVal(100);
        System.out.println("修改完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2[i].length; j++) {
                System.out.print(testArray2[i][j].getVal()+" ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3[i].length; j++) {
                System.out.print(testArray3[i][j].getVal()+" ");
            }
        }
        System.out.println();
    }
  }
拷贝完成
0 0 0 0 
0 0 0 0 
修改完成
100 0 0 0 
100 0 0 0 
  • System.arraycopy():
 for (int i = 0; i < testArray2.length; i++) {
            System.arraycopy(testArray2[i], 0, testArray3[i], 0, testArray2[i].length);
        }
  • Arrays.copyOf():
 for (int i = 0; i < testArray2.length; i++) {
            testArray3[i] = Arrays.copyOf(testArray2[i], testArray2[i].length);
        }

匿名数组

 使用数组时,一般需要先声明数组变量,然后创建并初始化一个数组并赋值给声明的数组变量。Java语言也支持匿名数组,即在需要数组变量的地方,直接通过下列形式创建一个匿名数组。

  • new 数组类型[] {初始值设定项}; //创建一个一维匿名数组
  • new 数组类型[][] {初始值设定项};//创建一个二维匿名数组

可变参数

 Java可变参数,适用于参数个数不确定,类型确定的情况,Java把可变参数当做数组处理。
  可变参数使用时需要注意:
  1.只能出现在参数列表的最后;
  2.“…”位于变量类型和变量名之间,前后有无空格都可以;
   3.调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。

时间复杂度:

 一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。 时间复杂度,在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
  按数量级递增排列,常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n), 线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),…, k次方阶O(nk),指数阶O(2n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。

数组的排序

  • 冒泡排序
  • 直接插入排序
  • 选择排序

冒泡排序

 冒泡排序(Bubble Sort),又被称为气泡排序或泡沫排序。它是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止!
 图文举例冒泡排序过程:数组{20,40,30,10,60,50}排序
在这里插入图片描述

  • 举例:
public class PaiXu {
    public static void MaoPao(int[] array){
        int tmp = 0;
        Boolean swap = true;
        for(int i = 0;i <= array.length-1; i++){
          for(int j = 0;j < array.length-1-i;j++){
              if(array[j] > array[j+1]){
                  tmp = array[j];
                  array[j] = array[j+1];
                  array[j+1] = tmp;
                  swap = true;
              }
          }
          if (!swap){
              break;  //冒泡排序及优化
          }
      }
    }
 public static void main(String[] args) {
        int[] array={2,1,5,10,3,8};
        MaoPao(array);
        System.out.println(Arrays.toString(array));
        }
}
[1, 2, 3, 5, 8, 10]
  • 冒泡排序时间复杂度
     最坏的时间复杂度为O(n^2),最好的时间复杂度为O(n)。
  • 冒泡排序的稳定性
     冒泡排序是稳定的算法,它满足稳定算法的定义。
     算法稳定性 – 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

直接插入排序

 直接插入排序(Straight Insertion Sort)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。

  • 举例:
public class PaiXu {
public static  void insert(int[] array){
        int tmp = 0;
        int j = 0;
        for(int i = 1;i < array.length;i ++){
            tmp = array[i];
            for(j = i - 1;j >= 0; j --){
                if (array[j] > tmp){
                    array[j + 1] = array[j];
                }else{
                    break;
                }
            }
            array[j + 1] = tmp;
         }                 
   }
    public static void main(String[] args) {
        int[] array={2,1,5,10,3,8};
        insert(array);
        System.out.println(Arrays.toString(array));
        }
  }
[1, 2, 3, 5, 8, 10]
  • 直接插入排序时间复杂度
     最坏的时间复杂度为O(n^2),当数组有序时,最好的时间复杂度为O(n)。
  • 直接插入排序的稳定性
     直接插入排序是稳定的算法,它满足稳定算法的定义。
     算法稳定性 – 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

选择排序

 选择排序(Selection sort)是一种简单直观的排序算法。它的基本思想是:从数组的第一个元素开始,与其后面相邻的元素比较大小,如果大于则交换次序,以此类推,直到所有元素均排序完毕。

  • 举例:
public class PaiXu {
public static void selectedSort(int[] array){
        int tmp = 0;
        for (int i = 0;i < array.length;i ++){
            for (int j = i+1;j < array.length;j++){
                if(array[i] > array[j]){
                    tmp = array[i];
                    array[i] = array[j];
                    array[j] = tmp;
                }
            }
        }                         
    }
   public static void main(String[] args) {
        int[] array={2,1,5,10,3,8};
        selectedSort(array);
        System.out.println(Arrays.toString(array));
   }
}
[1, 2, 3, 5, 8, 10]
  • 选择排序时间复杂度
     最坏的时间复杂度为O(n^2),当数组有序时,最好的时间复杂度为O(n)。
  • 选择排序的稳定性
     选择排序是不稳定的算法,它是跳跃式的交换次序。
    以上的排序方法都是升序排列,排序是在内部排序,在内存中处理。还有Arrays.sort() 方法也是升序排序的一种方法,底层是优化后的快速排序,相关具体例子在上一节博客中。
  • 练习:3阶魔方阵。
package mypratice;
import java.util.Scanner;
/**
 * @Package: mypratice
 * @Author:kkz
 * @Description:
 * @Date:Created in 2018/10/24 0:34
 */
public class Mofang {
      private static void Magic(int n){
            int[][] array= new int[n][n];   //定义二位数组,默认赋0值
            int row = 0;
            int col=n/2;          //行列赋初值
            for(int i = 1;i <= n * n;i ++){
                array[row][col] = i; //将1-9放入魔方阵中
                row --;
                col ++; //放在第一个数的上一行,下一列
                //行列同时越界:放到上个数的正下方
                if(row < 0 && col >= n){
                    row += 2;
                    col --;
                }
                // 行越界:把这个数放到同列的末行
                else if(row < 0){
                    row = n-1;
                }
                // 列越界:把这个数放到同行的首列
                else if(col >= n){
                    col = 0;
                }
                //冲突: 放到上个数的正下方
                else if(array[row][col] != 0){
                    row += 2;
                    col --;
                }
            }
//打印数组
            for(int i = 0;i < n;i ++){
                for(int j = 0;j < n;j ++){
                System.out.print(array[i][j] + "  ");
                }
                System.out.println();
            }
        }
public static void main(String[] args) {
//输入n的值
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        Magic(n);
    }
}
3
8  1  6  
3  5  7  
4  9  2  

Over…

猜你喜欢

转载自blog.csdn.net/nn1__2970/article/details/83280997
今日推荐