java 数组练习3

/*

  • 排序算法
  • 通常排序的目的是为了快速查找
  • 衡量排序算法的优劣
  • 1,时间复杂度:分析关键字的比较次数和记录的移动次数
  • 2,空间复杂度:分析排序算法需要多少辅助内存
  • 3,稳定性:若两个记录A和B的关键字值相等,但排序后A,B的先后次序保持不变,则称这种排序算法是稳定的

*排序算法分类:内部排序,外部排序
*1,内部排序:排序过程不需要借助外部储器,所有排序操作在内存中完成
*2,外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助外部存储器,
*外部排序最常见的是多路归并排序,可以认为外部排序是由多次内部排序组成
*
*十大内部排序算法
*1选择排序
*直接选择排序,堆排序
*2,交换排序
*冒泡排序(最简单),快速排序(常用速度快)
*3,插入排序
*直接插入排序,折半插入排序,Shell排序(希尔排序)
*4,归并排序
*5,桶式排序
,6,基数排序
*
*算法的五大特征
*1,输入(Input) :有0个或多个输入数据,这些输入必须有清楚的描述和定义
*2,输出(Output) : 至少有一个输出结果,不能没有输出结果
*3,有穷性(Finiteness) :算法可以在有限步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的
*时间内完成
*4,确定性(Definiteness) : 算法中的每一步都有确定的含义,不会出现二义性
*5,可行性(Effectiveness) : 算法中的每一步都是清楚且可行的,都能让用户用纸笔计算而求出答案
*说明:满足确定性的算法也称为:确定性算法,现在有更广泛的概念,会考虑各种非确定算法,例如并行算法,概率算法
*等,另外也有并不要求终止的计算描述,这种描述也被成为过程(procedure).
*
*
*排序算法之间的比较
*1,从平均时间看,快速排序算法最佳但在最坏情况下不如堆排序与归并排序
*2,从算法简单性看,直接插入排序,直接选择排序与冒泡排序最简单,被认为是简单算法
*对于shell排序,堆排序,归并排序与快速排序,算法复杂,认为是复杂排序
*3,从稳定性看,直接插入,冒泡与归并排序是稳定的,直接选择,堆排序,快速排序与shell排序是不稳定的
*4,从待排序数据长度N来看,N较小时宜采用简单排序,较大时采用改进排序
*
*算法的选择
*1,当n较小时例如<=50 ,可采用直接插入或直接选择排序
*当记录规模较小时,直接插入排序较好,否则因为直接选择移动的记录数小于直接插入,应选择直接选择排序
*2,若数列初始状态基本有序(正序),则应用直接插入,冒泡或随机的快速排序
*3,若数据规模较大,应用时间复杂度为nlogn的算法如快速排序,堆排序,归并排序
*
*Arrays工具类的使用
*java.util.Arrays 中提供了数组的输出,填充,赋值,反转,二分查找,排序等功能
*可以查询API文档
*/

/*

  • 冒泡排序
  • 简介:重复游走要排序的数列,一次比较两个元素,如果顺序错误就把他们交换过来
  • 排序思想:
  • 1,比较相邻的元素,如果第一个比第二个更大(升序情况),就交换两个的顺序
  • 2,对每一个相邻元素做同样的工作,从开始第一对到结尾的最后一对,这个步骤完成后,结尾的数就是最大的。
  • 3,针对所有元素重复上一个步骤,除了最后一个
  • 4,对越来越少的数据重复以上步骤,直到没有任何一对数字需要调换位置
  • 直接选择排序
  • 1,比较第一个元素和第二个元素,如果第二个比第一个小则交换位置
  • 2,再比较第一个和第三个一直到最后一个,这样第一个元素位置就是数组的最小值
  • 3,对第二个位置采用以上步骤,保证第二个元素的位置是除了第一个元素最小的
  • 4,重复以上方式直到最后一个位置
  • 直接插入排序
  • 1,比较第一个和第二个元素,如果第二个元素小于第一个则交换位置,形成一个长度为2的有序数列
  • 2,比较第三个元素和第二个元素的大小,如果小与第二个元素则向前比较,直到找到不小于前一个元素的位置。
  • 3,将此位置之后的元素依次向前移动一位,将第三个元素插入到此位置
  • 4,重复以上步骤直到最后一位。
    */

/*

  • 快速排序
  • 快速排序比同为O(nlogn)的其他算法更快,常被采用,而且采用分治法的思想
  • 由Tony Horare发明,是迄今为止内排序算法中最快的一种,属于交换排序的一种,是
  • 冒泡排序的升级版。
  • 排序思想:
  • 1,从数列中挑选一个元素成为基准(pivot).
  • 2,重新排序数列,所有元素比基准值小的放在基准值前,所有元素比基准值大的放在基准后
  • 相同的数可以放在任意一边,这个分区结束后,该基准就处于数列的中间位置,这个步骤称为分区操作(partition).
  • 3,递归(recursive)把小于基准值的子数列和大于基准值的子数列排序
  • 4,递归的最底部情况是数列的大小是0或1,也就是永远被排序好了,,虽然一直递归下去,但算法总会结束,因为在每次迭代(iteration)
  • 中,它至少会把一个元素摆到它最终的位置去。
  • 数组中的常见异常
  • 1,数组角标越界的异常:ArrayIndexOutOfBoundsException
  • 角标超出数组的角标范围【0,length】
  • 2,空指针异常:NullPointerException(常见)
  • 1,情况1,数组没有初始化,或者数组栈空间新赋值为null,堆空间地址被擦除
  • int[] arr = new int[3];
  • arr = null;
  • System.out.println(arr);//输出null
  • System.out.println(arr[0]);//错误
  • int[][] arr1 = new int[4][];
  • System.out.println(arr[0]);//输出默认值null
  • System.out.println(arr[0][0]);//错误
  • 2,情况2,调用null
  • String[] arr2 = new String[]{null,“A”,“B”,“C”};
  • System.out.print(arr2[0]);//输出null
  • System.out.print(arr2[0].toString());//调用null,错误
    */
package com.atguigu.contact;
import java.util.*;
public class Array4 {
    public static void main(String[] args) {    	
    	Scanner scan = new Scanner(System.in); 
    	System.out.println("请输入随机数组的长度");
	    int length = scan.nextInt();
	    int[] array = new int[length];
	    for (int l = 0; l < array.length; l++) {
	    	array[l] = (int)(Math.random() * 201 - 100);//随机数组范围【-100,100】		    
	    }
	    for (int l = 0;l < array.length;l++) {
	    	System.out.print(array[l] + " ");	    	
		}
	    System.out.println();
	    
        //直接插入排序
	    for (int i = 1; i < array.length; i++) {
			int temp,k;
			temp = array[i];//待比较的元素存入临时变量中
			k = i;
			for (;k > 0 && array[k - 1] >= temp;) {
				 array[k] = array[k - 1];//依次移动之前比temp大的元素到下一位置
				 k--;//角标每次自减一,直到array[k - 1]小于待比较大元素
			}	
			array[k] = temp;//将要比较的元素插入位置k
		}
	    	    
	    for (int l = 0;l < array.length;l++) {
	    	System.out.print(array[l] + " ");	    	
		}
	    System.out.println();
	    
	    //直接选择排序
	    for (int i = 0; i < array.length -1; i++) {
			int k = i;
			int temp = 0;
			for (int j = i; j < array.length; j++) {
				if(array[j] < array[k]) {					
					k = j;//如果找到一个更小的值则K的角标变换为次值的角标,最后k是最小值的角标
				}
			}
			temp = array[i];
			array[i] = array[k];
			array[k] = temp;//将找到的最小值与本次外层循环的第一个数值交换位置
		}
	    for (int l = 0;l < array.length;l++) {
	    	System.out.print(array[l] + " ");	    	
		}
	    System.out.println();
	    
	    
	    //冒泡排序
	    
    	for (int i = 0; i < array.length -1; i++) {//外层循环控制轮数
			for (int j = 0; j < array.length - 1 - i; j++) {//内层循环控制比较交换次数,每一轮去掉最后一位,需要-i
				if(array[j] > array[j + 1]) { //array[j] < array[j + 1]表示降序
					int temp = array[j];
					array[j] = array[j + 1];
					array[j + 1] = temp;//如果顺序错误则交换位置
				}
			}
				
			}
	
    	for (int l = 0;l < array.length;l++) {
	    	System.out.print(array[l] + " ");	    	
		}
	    System.out.println();
	    
		//Arrays工具类的使用
	    //创建数组测试使用
	    System.out.println("请输入随机数组的长度");
	    int length1 = scan.nextInt();
	    int[] array1 = new int[length1];
	    for (int l = 0; l < array1.length; l++) {
	    	array1[l] = (int)(Math.random() * 201 - 100);//随机数组范围【-100,100】		    
	    }
	    for (int l = 0;l < array1.length;l++) {
	    	System.out.print(array1[l] + " ");	    	
		}
	    System.out.println();
	    int[] array2 = new int[0];//数组可以是空集,长度是0
	    int[] array3 = new int[] {1,2,3,4,5,6};
	    int[] array4 = new int[] {1,2,6,5,4,3};
	    int[] array5 = new int[] {23,-45,78,34,22,11,89,36,-34,-99,28,0,5,1};
	    //比较两个数组,判断是否相等
	    boolean mark0 = Arrays.equals(array3, array4);
	    boolean mark1 = Arrays.equals(array3, array4);//位置不同,数组也不同
	    System.out.println(mark0 + "" + mark1);
	    //输出数组元素
	    System.out.println(Arrays.toString(array2));
	    System.out.println(Arrays.toString(array3));
	    for (int i : array3) {//另一种输出方法
			System.out.print(i + " ");
		}
	    System.out.println();
	    //将指定数字填充到数组中
	    Arrays.fill(array3, 2);
	    System.out.println(Arrays.toString(array3));//数组中的所有元素都会被填充为指定数值
	    //对数组排序
	    Arrays.sort(array4);
	    System.out.println(Arrays.toString(array4));
	    Arrays.sort(array5);
	    System.out.println(Arrays.toString(array5));//底层调用双基准快速排序实现
	    //二分查找,输出被查找元素的角标,前提是数组已被排序好
	    int index = Arrays.binarySearch(array5, 11);
	    int index1 = Arrays.binarySearch(array5, 13);//返回正数代表角标,负数代表没找到不存在
	    System.out.println(index + "" + index1);
	    if(index1 >= 0) {
	    	System.out.println(index1);
	    }else {
	    	System.out.println("未找到");
	    }
	    //数组的复制
	    int[] array6 = new int[array5.length];
	    array6  = Arrays.copyOf(array5,array5.length);
	    System.out.println(Arrays.toString(array6));
	    int[] array7 = new int[array5.length];
	    array7 = array5.clone();//另一种方法
	    System.out.println(Arrays.toString(array7))}        
}

你可能感兴趣的:(java,学习笔记)