zoukankan      html  css  js  c++  java
  • 009.day07

    day07笔记

    一、数组排序

    1. 冒泡排序

    每两个元素比较,按照从小到大顺序时,两两找出较大值,可能会发生交换,将较大值放在右侧,按照从大到小顺序时,两两比较找出较小值,可能会发生交换,将较小值放在右侧

    • 代码实现(由小到大)

      • 第一种写法

        // TODO 冒泡排序
        		int[] a = { 34, 23, 77, 66, 3, 145 };
        		// 排序的次数:数组元素的个数减一(当最后一个数的时候就不用排了)
        		for (int i = 0; i < a.length - 1; i++) {
                     // 当第一层循环到达i次时,第二层循环就可以减去第一次循环已经排好的次数,所以for循			 // 环跳出的条件为a.length - 1 - i
        			for (int j = 0; j < a.length - 1 - i; j++) {
        				// 两个数字的比较,从左至右,从小到大
        				if (a[j] > a[j + 1]) {
                         //亦或交换位置格式为三行
                         // a = a ^ b
                         // b = a ^ b
                         // a = a ^ b
        					a[j] = a[j] ^ a[j + 1];
        					a[j + 1] = a[j] ^ a[j + 1];
        					a[j] = a[j] ^ a[j + 1];
        				}
        			}
        		}
        		for (int temp : a) {
        			System.out.println(temp);
        		}
        
      • 第二种写法

    // TODO 冒泡排序
    		int[] a = { 34, 23, 77, 66, 3, 145 };
    		// 排序的次数:数组元素的个数减一
    		for (int i = 0; i < a.length - 1; i++) {
    			// j的取值为当前数组能够取到的下标减去已经排好的数(已经执行排序的次数)
    			for (int j = a.length - 1; j > i; j--) {
    				// 两个数字的比较,是否交换
    				// 从左至右,从小到大
    				if (a[j - 1] > a[j]) {
    					a[j] = a[j] ^ a[j - 1];
    					a[j - 1] = a[j] ^ a[j - 1];
    					a[j] = a[j] ^ a[j - 1];
    				}
    			}
    		}
    		for (int temp : a) {
    			System.out.println(temp);
    		}
    

    小练习

    需求:将学生对象按照ID大小排序

    //这是一个学生对象
    public Student(Integer id, String name) {
    		this.id = id;
    		this.name = name;
    	}
    	private Integer id;
    	private String name;
    	
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    // 测试
    public static void main(String[] args) {
    		Student[] students = new Student[3];
    		students[0] = new Student(2,"sand");
    		students[1] = new Student(1,"yokii");
    		students[2] = new Student(0,"Agiao");
    		// 经过排序后,数组中的对象按照学号正序
    		for (int i = 0; i < students.length; i++) {
    			for (int j = 0; j < students.length - 1 - i; j++) {
    				if (students[j].getId() > students[j + 1].getId()) {
    					Student temp = null;
    					temp = students[j];
    					students[j] = students[j + 1];
    					students[j + 1] = temp;
    				}
    			}
    		}
    		for (Student student : students) {
    			System.out.println(student.getId());
    		}
    	}
    

    2. 选择排序

    冒泡算法的改进,每次从当前比较的一组数中选出最值,排好一个数,只进行一次交换

    • 代码实现
    // TODO 选择排序
    		int[] a = { 34, 23, 77, 66, 3, 145 };
    		// 排序的次数:数组元素的个数减一
    		for (int i = 0; i < a.length - 1; i++) {
    			// 每次指向a[0]
    			int max = 0;
    			// 这一层循环的目的是找到这一次循环中最大数的下标为max
    			// (优化)第二层循环可以减去第一层循环已经排好的数
    			for (int j = 1; j < a.length - i; j++) {
    				if (a[j] > a[max]) {
    					max = j;
    				}
    			}
    			// 判断找到的最大数是否为第一层循环的当前最后一个
    			// 如果不是,则将当前获取到的最大的数与第一层循环的当前最后一个交换位置
    			// a ^ a = 0(亦或运算->相同为0,不同为1)
    			if (max != a.length - i - 1) {
    				/*int temp = a[max];
    				a[max] = a[a.length - i - 1];
    				a[a.length - i - 1] = temp;*/
    				a[max] = a[max] ^ a[a.length - i - 1];
    				a[a.length - i - 1] = a[max] ^ a[a.length - i - 1];
    				a[max] = a[max] ^ a[a.length - i - 1];
    			}
    		}
    		for (int i : a) {
    			System.out.println(i);
    		}
    

    3. Arrays工具类

    • Arrays所在包:java.util
    • sort方法:将数组的元素按照自然序列排序(基本数据类型),也可以自定义排序规则
    • 使用规则:无返回值类型,直接传入数组变量作为参数
    int a[] = {25,66,7,8,43,200}
    Arrays.sort(a);
    

    二、数组查找

    1. 二分法查找

    在一个有序数组中查找一个数,返回其所在位置

    • 代码实现
    		// TODO 有序数组的二分查找
    		int[] a = {3,20,10,5,67,103};
    		Arrays.sort(a);
    		for (int i : a) {
    			System.out.print(i + "  ");
    		}
    		System.out.println();
    		System.out.println("请输入要查找的数:");
    		Scanner scanner = new Scanner(System.in);
    		// n为要查找的数
    		int n = scanner.nextInt();
    		// 初始化用于标记区间的变量
    		int left = 0;
    		int right = a.length - 1;
    		// 初始化每次用于比较的变量的下标
    		int middle = (left + right) / 2;
    		// 标记是否已经找到相应的数字
    		int location = -1;
    		// 当要查找的数不存在于数组中时,left>right,跳出循环
    		while(left <= right) {
    			if (a[middle] == n) {
    				// 找到时,标记下标位置,并且跳出
    				location = middle;
    				break;
    			}else if (n > a[middle]) {
    				// 在右侧区间中,将left指标右移
    				left = middle + 1;
    				middle = (left + right) / 2; 
    			}else {
    				// 在左侧区间中,将right指标左移
    				right = middle - 1;
    				middle = (left + right) / 2; 
    			}
    		}
    		// 当找到这个数时,location改变为这个数的下标
    		if (location != -1) {
    			System.out.println("位置为" + (location + 1));
    		}else {
             // 找不到这个数时,location的值没有改变为-1
    			System.out.println("数组中没有该元素");
    		}
    		scanner.close();
    

    三、数组扩容

    数组定义后长度固定,可以新建一个数组,迁移原数组数据,并提供更多的空间放入新数据

    ArrayList的add方法(用于向集合中添加新的元素):ArrayList底层通过数组结构实现,过程与数组扩容步骤类似

    需求:用户从控制台不断的录入数据,当数据录入的个数已经超过数组容量时可以自动扩容,继续接受元素

    步骤:

    ​ 定义一个数组(a),例如长度为5
    定义一个变量,记录用户输入了几个数据,即数组(a)中已经添加了几个元素
    每次用户输入数据时,使用变量判断是否超出了当前数组(a)的长度
    如果超出,定义一个新的数组(b),复制原来数组中的数据到新数组(b)
    将新输入的元素添加到数组(b)中,并将新数组赋值给原数组(a)

    • 代码实现
    // 定义全局变量数组a
    static int[] a = new int[3];		
    public static void main(String[] args) {
    		// TODO 数组扩容
             // 实例化扫描器
    		Scanner scanner = new Scanner(System.in);
    		//控制是否继续输入数据  
    		boolean flag = true;
    		// 标记数组当前存储元素的个数
    		int index = 0;
    		while(flag) {
    			System.out.println("请输入一个数");
    			int number = scanner.nextInt();
    			if (index == a.length) {
                    //当index自增到与a数组的长度相等时调用扩容方法
    				extend();
    			}
             // 先把输入的输赋给a[index],然后index再自增
    			a[index ++] = number;
    			scanner.nextLine();
    			System.out.println("是否继续输入y/n");
    			String input = scanner.nextLine();
    			if ("y".equals(input)) {
    				flag = true;
    			}else {
    				flag = false;
    			}
    		}
    		for (int number : a) {
    			System.out.println(number);
    		}
    		scanner.close();
    	}
    	
    	/**
    	 * 将原数组数据保留下来,并扩充空间
    	 */
    	public static void extend() {
            // new一个新数组,长度为原来数组的长度+1
    		int[] b = new int[a.length + 1];
    		for (int i = 0; i < a.length; i++) {
                // 保留原数据
    			b[i] = a[i];
    		}
            // 把保存了原数据并扩容后的新数组b赋给原数组a
            // 也就是把a指向b的地址
    		a = b;
    	}
    

    四、数组结构(与链表比较)

    • 数组适合数据的查找,不适合元素的更新,原因:连续的空间
    • 链表不适合数据的查找,适合元素的更新,原因:拆下或插入新节点容易

  • 相关阅读:
    怎样解决:未找到路径“……”的控制器或该控制器未实现 IController?
    错误:org.springframework.jdbc.support.SQLErrorCodesFactory
    springbean的生命周期
    注解到处excel
    nio读取文件,输出文件
    AtomicReference
    唯一id
    hashmap1.7的死锁模拟
    数组模拟stack
    环形队列
  • 原文地址:https://www.cnblogs.com/yokii/p/9345679.html
Copyright © 2011-2022 走看看