java基础知识(三)

*经典数组赋值语句
int[] Arr = new int[]{1,2,3,4,5};
//从右向左执行,在堆内存中创建了长度指定,元素指定的一维int型数组,在主函数中创建了一个名为Arr的变量,将数组在堆内存中的地址赋给Arr一维数组型变量,以供Arr调用,从而实现对数组元素中的改变;

Arr[2] = 10;
//角标为2,事实上是第三个元素,将10这个整型值赋给Arr数组中的第三个元素

int[] Arr2 = arr;
//*易混淆点,此处实际并未开辟堆内存中的新空间,只不过是变量间的赋值,但是不是赋的是一个具体的数值,而是将Arr变量的地址赋给了Arr2这个变量,但是Arr的地址实际是堆内存中一维数组的地址,此时指向一维数组的变量有两个,Arr从而将地址赋给Arr2,使Arr2获得了对一维数组的调用访问修改数值的权利;

Arr2[2]= 20;
//Arr2变量通过地址寻找访问到了一维数组(仅有的一个数组)并对其中角标为2,实际为一维数组中的第三个元素进行了重新赋值为20,数组中实际第三个元素值已经变更为20
System.out.println(Arr[2]);//此时调用打印输出语句,打印的是Arr变量访问一维数组中的角标为2,实际为第三个元素,但是刚才Arr2已经通过变量地址访问到并修改其值,此时Arr变量在访问并打印,实际打印出来的为20;

Arr=null;
//将Arr中的变量地址赋值为空,此时Arr已无法通过地址查找访问一维数组。

System.out.println(Arr[2]);
//此时仍是将Arr[2]元素打印出来,但是Arr变量地址已经赋值为空,Arr变量此时将再无法访问一维数组,但是整体输出语句语法没有错误,编译不会出错,但是运行时泽会出现java.lang.NullPointerException (空指针异常)

当一个对象(数组或者后面所学知识点)再也没有被其他变量引用(此时已无变量知道对象在堆内存中的地址)时,就变成了垃圾(由垃圾回收器自动回收)

java中字符串和数组分别获得长度的方法
//字符串String的长度    length() 函数
//数组[]的长度    length 属性/变量

二分搜索
二分搜索的前提为数组是有序的,数组已经按照正序或者逆序排列,时间复杂度O(n)更低,仅为log以2为低n的对数,因为没进行一次搜索,就可以排除一半的元素,但在加快搜索的同时,空间变得更加复杂了;
二分搜索的代码实现

数组的扩容
(1)数组的长度一旦确定不可以更改(本质为为数组开辟的连续空间大小不可变)
(2)数组的扩容或者缩容的本质并不是在原数组上进行操作的,而是在堆内存中重新开辟了新的空间,创建了我们的一个新数组,长度为你想扩容的长度,或者你想缩容的长度,然后再用一次for循环对短数组进行一次遍历,在逐个将原数组的元素赋值给新数组,这样一来,就完成了我们所谓的扩容或者缩容操作,我们感知上我们的数组扩大了,其实扩大之后的数组已经成为了另一个数组,在之后,若原数组,再也没被引用的情况下,原数组在堆内存中占用的空间将由java中的垃圾处理机制,对原数组进行清理,清空所有的值,并将开辟的空间清空;

哈希表|散列表()

常见的异常合集
//OutOfMemoryError 
    堆内存溢出(存对象的地方) 数组大小过大
//StackOverFlowError 
    栈内存溢出(函数运行时出现的问题) 
//java.lang.NullPointerException
    这个异常都是因为调用null对象的方法,就是一个对象还没有正常的出事话,就先调用它的方法,比如 Object obj=null; obj.toString();这就会抛出这个异常;

对一维无序数组的排序方法

(1)冒泡排序
    思路:首先需要两个嵌套的for循环,外层的for循环控制轮数,i同时也代表指针所在位置,内存的for循环则控制每轮比较的次数,j同时也代表指针所在位置.
  外部循环首指针指向第i个元素,同时整体外部循环控制轮数,内部循环首指针指向第i+1个元素,排序过程中始终为当前元素与其后一个元素进行比较,第i个元素如果大于第i+1个元素,则交换位置,否则两元素相对位置不变,以此思路比完一轮,即可知末尾元素应为最大元素,此时外部控制循环轮数减1,内部循环控制比较次数同时减一,即可知倒数第二位的元素为倒数第二大的元素,依次进行比较并且内部交换,当所有轮数进行比较完之后,自然而然会给出无序数组从小到大的排列方式;
时间复杂度:采用双层for循环,时间复杂度为O(n^2)
比较方式:每一个数字都要和其他数字比较一下

冒泡排序的代码实现

import java.util.Arrays;
class BubbleSort{
    public static void main(String[] args){
        int[] a={6,4,9,1,8,3,2,7,5};
        for(int i=0;i<a.length-1;i++){
            for(int j=0;j<a.length-1-i;j++){
                if(a[j]>a[j+1]){
                    swap(a,j,j+1);
                }
            }
        }
        System.out.println(Arrays.toString(a));
    }
    public static void swap(int[] a,int i,int j){
        int temp=a[i];
        a[i]=a[j];
        a[j]=temp;
        //+-+
        //^^^
    }
}


(2)选择排序
    思路:首先需要两个嵌套的for循环,外层的for循环控制轮数,i同时也代表指针所在位置,内存的for循环则控制每轮比较的次数,j同时也代表指针所在位置.
  外部循环首指针指向第i个元素,同时整体外部循环控制轮数,内部循环首指针指向第i+1个元素,排序过程中始终为当前元素与i+1(j)之后的所有元素进行比较,如果第j个元素如果小于第i个元素,则交换位置,否则两元素相对位置不变,以此思路比完一轮,即可知首位元素应为最小元素,此时外部控制循环轮数减1,内部循环控制比较次数同时减一,即可知正数第二位的元素为倒数第二小的元素,依次进行比较并且内部交换,当所有轮数进行比较完之后,自然而然会给出无序数组从小到大的排列方式;
时间复杂度:采用双层for循环,时间复杂度为O(n^2)
比较方式:每一个元素都要和其他元素进行比较

选择排序的代码实现

import java.util.Arrays;
class SelectSort{
    public static void main(String[] args){
        int[] a={6,4,9,1,8,3,2,7,5};
        for(int i=0;i<a.length-1;i++){
            for(int j=i+1;j<a.length;j++){
                if(a[i]>a[j]){
                    swap(a,i,j);
                }
            }
        }
        System.out.println(Arrays.toString(a));
    }
    public static void swap(int[] a,int i,int j){
        int temp=a[i];
        a[i]=a[j];
        a[j]=temp;
        //+-+
        //^^^
    }
}

(3)插入排序
    思路:将数组的第一个数认为是有序数组,从后往前(从前往后)扫描该有序数组,把数组中其余n-1个数,根据数值的大小,    插入到有序数组中,直至数组中的所有数有序排列为止。这样的话,n个元素需要进行n-1轮排序!
(1)外层循环表示的是排序的趟数,n个数字需要n-1趟,因此,外层循环的次数是n-1次;同时也代表数的位置。
(2)内层循环表示的是每一趟排序的数字。根据插入排序的思想,第i趟排序时,有序数组中的数字就有i个,就需要进行i次比较,因此循环i次。注意采用的是从后往前进行比较。
举个例子:4个数字4,6,7,5进行从大到小的排序。前插排序法具体过程如下:
把第一个数4插入到空的有序数组中的第一个位置上,得到新数字序列4;

第一趟:从后往前扫描有序数组,将第二个数字6和有序数组中的4进行比较,6大于4,此时将4后移一个位置。此时已经扫描完有序数组中的数,将6插入到4的前面(有序数组的第一个位置),得到新数字序列6,4;

第二趟:从后往前扫描有序数组,先将第三个数字7和有序数组中的4进行比较,7大于4,此时将4后移一个位置;再将7和有序数组中的6进行比较,7大于6,此时将6后移一个位置。此时已经扫描完有序数组中的数,将7插入到6的前面(有序数组的第一个位置),得到新数字序列7,6,4;

第三趟:从后往前扫描有序数组,先将第四个数字5和有序数组中的4进行比较,5大于4,此时将4后移一个位置;再将5和有序数组中的6进行比较,5小于6,由于有序数组就按照从大到小排列的,此时直接把5插入到4的前面即可!不需要再和7进行比较!最后,得到新数字序列7,6,5,4;
时间复杂度:采用双层for循环,时间复杂度为O(n^2)
比较方式:并不是每个元素和其他元素进行比较;如果左边的数字比当前小,意味着左边一切都比它小且有序

插入排序的代码实现

import java.util.Arrays;
class InsertSort{
    public static void main(String[] args){
        int[] a={6,4,9,1,8,3,2,7,5};
        for(int i=1;i<a.length;i++){
            int e=a[i];
            int j=i;
            while(j>0&&a[j-1]>e){
                a[j]=a[j-1];
                j--;
            }
            a[j]=e;
        }
        System.out.println(Arrays.toString(a));
    }
    public static void swap(int[] a,int i,int j){
        int temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}

二维数组

(1)声明二维数组的语法:
数据类型 [ ] [ ] 数组名 ;
或者
数据类型 数组名 [ ] [ ] ;//允许这种方式,但并不推荐使用


(2)实质:二维数组的实质其实是一个的数组,它的每个元素是一个一维数组;第一维代表行数,同时也代表为行在堆内存中开辟的空间;第二维代表列数,即每一行中有多少个元素,同时代表为列在堆内存中开辟的空间;
(3)获取长度的方式:假设创建一个二维数组 int [ ][ ] arr = new int [10] [10];
                              arr.length  实际上是获取元素数,也可以理解为行数
                              arr[i].length  实际上是获取每个元素中具体的个数,也可以理解为列数

经典五子棋(无图形化界面)的代码实现

import java.util.Scanner;
class WuZiQi{
    /*
    1.创建一个棋盘
    2.对棋盘进行初始化
    3.打印棋盘
    4.开始游戏
    */

    //1.
    public static String[][] board=null;
    public static Scanner scanner=new Scanner(System.in);

    public static void main(String[] args){
        //2.
        initBoard();
        //3.
        printBoard();
        //4.
        startGame();
    }
    public static void startGame(){
        int player=0;
        while(!isGameOver()){
            if(player%2==0){//黑方
                System.out.println(">>>黑方下棋:");
                if(!xiaqi("O")){
                    continue;
                }
            }else{//白方
                System.out.println(">>>白方下棋:");
                if(!xiaqi("X")){
                    continue;
                }
            }
            player++;
        }
        System.out.println(">>>游戏结束!!");
    }
    public static boolean isGameOver(){
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board.length;j++){
                if(!board[i][j].equals("+")){
                    //向右
                    if(j<11){
                        boolean flag=true;
                        for(int dy=1;dy<=4;dy++){
                            if(board[i][j]!=board[i][j+dy]){
                                flag=false;
                                break;
                            }
                        }
                        if(flag){
                            return true;
                        }
                    }
                    //向下
                    if(i<11){
                        boolean flag=true;
                        for(int dx=1;dx<=4;dx++){
                            if(board[i][j]!=board[i+dx][j]){
                                flag=false;
                                break;
                            }
                        }
                        if(flag){
                            return true;
                        }
                    }
                    //右下
                    if(i<11&&j<11){
                        boolean flag=true;
                        for(int d=1;d<=4;d++){
                            if(board[i][j]!=board[i+d][j+d]){
                                flag=false;
                                break;
                            }
                        }
                        if(flag){
                            return true;
                        }
                    }
                    //右上
                    if(i>3&&j<11){
                        boolean flag=true;
                        for(int d=1;d<=4;d++){
                            if(board[i][j]!=board[i-d][j+d]){
                                flag=false;
                                break;
                            }
                        }
                        if(flag){
                            return true;
                        }
                    } 
                }
            }
        }
        return false;
    }
    public static boolean xiaqi(String chess){
        System.out.print(">>>请输入x坐标:");
        int x=scanner.nextInt()-1;
        System.out.print(">>>请输入y坐标:");
        int y=scanner.nextInt()-1;
        if(board[x][y].equals("+")){
            board[x][y]=chess;
            printBoard();
            return true;
        }else{
            System.out.println(">>>棋子已存在,请重新下棋!");
            return false;
        }
    }
    public static void printBoard(){    //打印棋盘
        System.out.print("   ");
        for(int i=1;i<=15;i++){
            System.out.printf("%-3d",i);      //打印纵坐标,并让格式化输出
        }
        System.out.println();
        for(int i=0;i<board.length;i++){
            System.out.printf("%-3d",i+1);    //打印横坐标,并进行格式化输出
            for(int j=0;j<board[i].length;j++){    
                System.out.print(board[i][j]+"  ");   //将刚才已进行初始化填充的棋盘打印出来 
            }
            System.out.println();    //每打印一行棋,进行换行
        }
    }
    public static void initBoard(){    //初始化棋盘
        board=new String[15][15];    //为二维型字符串数组开辟空间为15*15
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board[i].length;j++){
                board[i][j]="+";    //棋盘的每一个坐标的初始化填充
            }
        }
    }
}

经典猜字符代码实现

import java.util.*;
class Class34{
    //1.先生成一组单词
    public static String[] words={"computer","since","datastruct","banana","sasuke","naruto","jiraya","hasake"};
    //2.随机抽取一个单词
    public static String word=null;    //主函数外初始化word字符,全局调用
    //3.创建该单词的一个状态数组
    public static boolean[] state=null;    //主函数外初始化与抽出word字符相对应的状态数组,全局调用
    //4.当前轮猜错的次数
    public static int missed=0;    //主函数外初始化并进行赋值初始化猜错次数,全局调用

    public static void main(String[] args){    //主函数中写具体实现方法,细节实现可写在自定义函数内,即可以避免代码冗余的同时逻辑结构也变得清晰起来
        Scanner scanner=new Scanner(System.in);    //初始化scanner方法
        Random random=new Random();    //初始化random方法
        word=words[random.nextInt(words.length)];
        state=new boolean[word.length()];
        
        //5.开始输入字符猜单词
        while(true){
            String password=getPassWord();
            System.out.print("Enter a letter in word "+password+":");
            String letter=scanner.nextLine();
            changeWordState(letter);
            if(isEnd()){
                System.out.println("The word is "+word+".You missed "+missed+" time");
                System.out.print("Do you want to guess another word?Enter y or n:");
                if(scanner.nextLine().equals("y")){
                    word=words[random.nextInt(words.length)];
                    state=new boolean[word.length()];
                    missed=0;
                }else{
                    break;
                }
            }
        }
    }
    public static boolean isEnd(){
        for(int i=0;i<state.length;i++){
            if(state[i]==false){
                return false;
            }
        }
        return true;
    }
    public static void changeWordState(String letter){
        boolean isExist=false;
        for(int i=0;i<word.length();i++){
            if((word.charAt(i)+"").equals(letter)){
                isExist=true;
                if(state[i]==false){
                    state[i]=true;
                }else{
                    System.out.println("\t"+letter+" is already in the word"); 
                    return;
                }
            }
        }
        if(!isExist){
            missed++;
            System.out.println("\t"+letter+" is not in the word");
        }
    }
    public static String getPassWord(){
        String password="";
        for(int i=0;i<word.length();i++){
            if(state[i]==true){
                password+=word.charAt(i);
            }else{
                password+="*";
            }
        }
        return password;
    }
}

资源链接:https://blog.csdn.net/weixin_43956598/article/details/90181567    (插入排序的具体实现细节)







 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值