其实编写程序就是把数据拿在手中玩儿,对不?
Java用来干嘛?
编写程序!程序又拿来干嘛?处理现实中的问题?什么问题?一系列复杂的逻辑,运算等!
其实,程序的功能就是为现实生活中遇到的问题进行服务。
为企业进行服务,处理数据,一切都是以数据为中心开展的活动!
数据才是核心!!!
既然数据如此重要,程序中如何处理各种数据呢?-------使用容器
处理数据时使用容器能够有效的对数据进行管理,非常方便!
必须滚瓜烂熟的掌握容器!!!
Java中用来存放数据的容器,各自有自身的特性,适用于不同的场景!
第一种:数组
一维数组
二维数组
第二种:集合
List集合
Set集合
Map集合
=============================================================
数组的常见操作
求最值
public class Test { /** * 求数组中的最大值 * @param args */ public static void main(String[] args) { //静态初始化一个int类型的数组, int[] arr = {-1,5,-2,8,3,0}; int maxElement = getMax(arr); System.out.println("maxElement="+maxElement); System.out.println("maxElement="+getMax2(arr)); } /** * 第一种思路:每次记录最大的数 * @param arr * @return */ public static int getMax(int[] arr) { //数组的第一个元素 int maxElement = arr[0]; for(int i=1; i<arr.length; i++) { if(arr[i] > maxElement) maxElement = arr[i]; } return maxElement; } /** * 第二种思路:每次记录最大数在数组中的角标位 * @param arr * @return */ public static int getMax2(int[] arr) { //数组的第一个角标 int maxElementIndex = 0; for(int i=1; i<arr.length; i++) { if(arr[i] > arr[maxElementIndex]) { maxElementIndex = i; } } return arr[maxElementIndex]; } }
数组的排序
【这里只是演示排序的思想,实际开发中不要用选择与冒泡进行排序,因为效率太低】
选择排序
原理:每次都以某个角标位为基准与后面的所有数进行比较。
实际上就是以角标为中心,每次把该角标上的数与后面的所有数进行比较。
选择排序,其特点是完全按照线性顺序逐个比较元素的,啃着1个位置与其它元素比较。
如,0号位元素,先与1号位元素比,发现1号位的元素更小,它们交互位置
交互位置后,0号位元素存放的是小值,
然后,再拿0号位这个'最小值'与2号位比较。。。
import java.util.Arrays; public class SelectSort { public static void main(String[] args) { int[] arr = new int[]{100,3,1,39,6,7,2}; sort(arr); System.out.println(Arrays.toString(arr)); } /** * 以升序为例 * 第1次:数组的0角标位始终用来存放最小值(每次比较如果有比它小的,则交换位置,将小的数放到0角标,然后再逐个与后面的数比较) * 第2次,数组的1号角标位又用来存放后面这些数中最小的那个值 * 依次类推 * 当角标位等于数组长度减2时,进行最后一次比较,即数组最后2个数之间比较 * @param arr */ private static void sort(int[] arr) { //外层:锁定每次排序用来存储最值的角标 //当i=arr.length-1的时候,实际已经为数组的最后一个元素了,一个数无需再比较了 for (int i = 0; i < arr.length-1; i++) { //内层:逐个比较,得到一个最值(最后1次比较时,j=arr.length-1) for (int j = i+1; j < arr.length; j++) { //后面的数更小,则交互位置 if(arr[j] < arr[i]) { arr[j] = arr[j] ^ arr[i]; arr[i] = arr[j] ^ arr[i]; arr[j] = arr[j] ^ arr[i]; } } } } }
优化选择排序
优化结果:减少数据交换位置的动作,每次遍历后都只对锁定角标位上的值与最值进行交换
import java.util.Arrays; public class SelectSortImprove { public static void main(String[] args) { int[] arr = new int[]{10,3,9,-1,8,7,6,5,4,3,2,1}; sort(arr); System.out.println(Arrays.toString(arr)); } /** * 选择排序的改进 * 改进的地方: * 每次比较出最小值,不立刻交换位置 * 而是记录最小值的角标,再拿这个角标的值与其它元素进行比较 * 一次遍历,得到最小值的角标,再与数组中锁定的角标位进行值的交换动作 * @param arr */ public static void sort(int[] arr) { for (int i = 0; i < arr.length-1; i++) { int minElementIndex = i; for (int j = i+1; j < arr.length; j++) { if(arr[minElementIndex]>arr[j]) { minElementIndex = j; } } if(i != minElementIndex) swap(arr,i,minElementIndex); } } private static void swap(int[] arr, int i, int minElementIndex) { arr[i] = arr[i] ^ arr[minElementIndex]; arr[minElementIndex] = arr[i] ^ arr[minElementIndex]; arr[i] = arr[i] ^ arr[minElementIndex]; } }
冒泡排序
import java.util.Arrays; public class BubbleSort { public static void main(String[] args) { int[] arr = new int[]{10,9,8,7,6,5,4,3,2,1}; sort(arr); System.out.println(Arrays.toString(arr)); } /** * 冒泡排序 * 特点:相邻元素逐个比较 * 一次遍历之后,大数都尽量往后靠了,并且最大的数放到了最后 * @param arr * @return */ private static void sort(int[] arr) { //外层:决定内层循环的次数 for (int i = 0; i < arr.length-1; i++) { //内层:比较相邻的元素 //-1 是为了防止角标越界 //-i是参与比较的元素递减 for (int j = 0; j < arr.length-i-1; j++) { //升序 if(arr[j]>arr[j+1]) { arr[j] = arr[j] ^ arr[j+1]; arr[j+1] = arr[j] ^ arr[j+1]; arr[j] = arr[j] ^ arr[j+1]; } } } } }
开发中这样排序
public static void main(String[] args) { //数组中元素的排序 int[] arr = new int[]{10,9,8,7,6,5,4,3,2,1}; //Arrays类提供了针对数组操作的方法 Arrays.sort(arr); System.out.println(Arrays.toString(arr)); //集合中元素的排序 List<BigDecimal> list = new ArrayList<BigDecimal>(); list.add(new BigDecimal(100.1)); list.add(new BigDecimal(20)); list.add(new BigDecimal(88.8)); //Collections类提供了对集合的排序(集合中的元素如果没有实现Comparable接口,则需要手动指定一个比较器) //BigDecimal extends Number implements Comparable<BigDecimal> Collections.sort(list); for(BigDecimal b : list) { System.out.println(b.doubleValue()); } }
数组中的查找
无序数组中查找元素
public class ArraySearch { /** * 无序数组的查找 * @param args */ public static void main(String[] args) { int[] arr = {1,5,2,7,4,0}; int key = 5; int index = searchElement(arr,key); System.out.println(key+"在数组arr中的角标位:"+index); } private static int searchElement(int[] arr, int key) { for(int i=0; i<arr.length; i++) { //无序数组的查找,只能挨个比较 if(arr[i] == key) return i; } return -1; } }
有序数组的查找
基于有序的特点,可以提高查找效率
由于数组有序,以升序为例,不用挨个比较,可以跳跃着比较,因为数组已经有序
【不要为了使用二分查找而对一个数组进行排序!这样已经没意义了,因为数组都变了!~】
被操作的数组前提是有序的(升序/降序),在此基础上才能使用二分查找法!
public class ArraySearch { /** * 有序数组的查找 * @param args */ public static void main(String[] args) { int[] arr = {1,3,5,7,9}; int key = 5; int index = binarySearch(arr,key); System.out.println(key+"在数组arr中的角标位:"+index); } private static int binarySearch(int[] arr, int key) { int min = 0, max = arr.length-1, mid = (min+max)>>1; //循环结束的条件:min 大于 max,再比较已经没有意义,循环结束 while(min <= max) { if(arr[mid] < key) { //中间数 < key,移动min角标,指向mid的后一位 min = mid + 1; } else if(arr[mid] > key) { // 中间数 > key,移动max角标,指向mid的前一位 max = mid - 1; } else { return mid; } //如果没有找到,从新定位mid的位置 mid = (min+max)>>1; } return -1; } }
开发中对有序数组这样查找
import java.util.Arrays; public class ArraySearch { /** * 使用Arrays类中的binarySearch方法对有序数组进行查找 * @param args */ public static void main(String[] args) { int[] arr = {1,3,5,7,9}; int key = 2; //binarySearch()对数组进行查找,底层做了2个操作 //1.如果查找到,则返回元素的角标 //2.如果没有找到,则告诉你该元素应该插入到数组的哪个位置(插入后数组仍有序): // index: -(insertion point) -1 ,既保证不存在时返回负数,又能明确了插入位置 int index = Arrays.binarySearch(arr, key); System.out.println(key+"在数组arr中的角标位:"+index); //返回-2 //表示数组中没有2这个元素,而且如果要插入到数组中,其角标位是 |(-2 + 1)| = 1 } }
数组的应用---进制转换---把数组当做一张表来使用
/** * 数组的灵活运用 * 查表法 * 一组数与另一组数有对应关系,则用数组来操作,用一个数组定义一个对应关系表 * 如果有对应关系,但是不连续,则用Map * 其实这里的数组是一个特殊的Map,其key就是数组的角标 * 而这个key就是程序中运算的结果,这样,直接从数组中取即可! * @param args */ public class ArrayUse { /** 使用数组定义一张映射关系表---10进制数与16进制的对应关系 玄机:转换为得到的10进制数与对应的16进制字符在表中的角标相同 */ static char[] hexTable = {'0','1','2','3','4', '5','6','7','8','9', 'A','B','C','D','E'}; public static void main(String[] args) { int num = 0; char[] retHex = toHex(num); for(char c : retHex) { if( Character.isDigit(c) || Character.isLetter(c) ) System.out.print(c); } } public static char[] toHex(int num) { //32位系统上,最多就是8个16进制 (32/4=8) int len = 8; //从数组的最后一位开始存,后面就不需要反转数组了 int pos = len -1; //定义一个用来存放转换后结果的数组 char[] hexResult = new char[len]; //do... whlie()保证至少执行一次,这样保证num==0的情况下也有结果 do{ // 15 的 2进制 : 1111,将最后4位与1111进行与 int temp = num & 15; //使用temp作为角标到表中查找对应的16进制字符 hexResult[pos--] = hexTable[temp]; // 取下一组4个比特位的数 num = num >>> 4; } while(num != 0); return hexResult; } }
10进制与其它进制的转换(整合)
public class ArrayUse { /** 使用数组定义一张映射关系表---10进制数与16进制的对应关系 玄机:转换为得到的10进制数与对应的16进制字符在表中的角标相同 */ static char[] baseTable = {'0','1','2','3','4', '5','6','7','8','9', 'A','B','C','D','E'}; /** 使用枚举存储进制类型 各进制中有一个属性:10进制转换为该进制每次移动的位数 */ static enum Base { binary(1),octal(3),hex(4); private int offset; private Base(int offset) { this.offset = offset; } } public static void main(String[] args) { int num = 60; int base = 2; char[] convert = numberConvert(num, base); for(char c : convert) { if( Character.isDigit(c) || Character.isLetter(c) ) System.out.print(c); } } /** * * @param num 需要进制转换的数 * @param base 进制 * @param offset 每次左移的位数 * @return */ public static char[] numberConvert(int num, int base) { //32位系统 int len = 32; //从数组的最后一位开始存,后面就不需要反转数组了 int pos = len -1; //定义一个用来存放转换后结果的数组 char[] hexResult = new char[len]; int offset = getOffestByBase(base); if(offset == -1) { throw new RuntimeException("指定的进制错误"); } //do... whlie()保证至少执行一次,这样保证num==0的情况下也有结果 do{ int temp = num & (base-1); //使用temp作为角标到表中查找对应的16进制字符 hexResult[pos--] = baseTable[temp]; // 取下一组4个比特位的数 num = num >>> offset; } while(num != 0); return hexResult; } private static int getOffestByBase(int base) { switch(base) { case 2: return Base.binary.offset; case 8: return Base.octal.offset; case 16: return Base.hex.offset; } return -1; } }
开发中这样使用进制转换
public static void main(String[] args) { int num = 60; //转为2进制 System.out.println(Integer.toBinaryString(num)); //转为8进制 System.out.println(Integer.toOctalString(num)); //转为16进制 System.out.println(Integer.toHexString(num)); }
相关推荐
通过以上实验,我们不仅学习了数组排序和折半查找算法的基础知识,还掌握了如何使用一维数组实现栈,并利用栈来解决实际问题——将十进制数转换为二进制数。这些技能对于深入理解数据结构和算法非常有帮助,并且能够...
在本压缩包“用Java实现基础数据结构,排序算法、经典算法以及leetcode刷题记录_Java_下载.zip”中,包含的资源主要是关于Java编程语言实现的数据结构、排序算法、经典算法以及LeetCode刷题的代码实现。这些是计算机...
Java数组是编程中基本的数据结构,它允许存储同类型的多个数据项,并通过索引来访问这些数据。本篇文章总结了十个重要的Java数组操作方法,适用于学习和复习Java编程知识。 1. **声明数组**: 在Java中声明数组时...
2. **数组**:数组是Java中存储固定数量相同类型元素的数据结构。它们提供了一种高效的方式来组织和访问数据。数组有索引,通常从0开始,通过索引可以快速访问和修改元素。了解数组的操作,如创建、遍历和数组方法,...
要求:用一个类来描述一个排序算法,类中的sort方法通过调用比较、交换方法来实现数组排序。排序类放入一个特定的包MySort中。 实验支持双输入,即如果有命令行输入,则不需要键盘输入。否则,自动提问,转为命令行...
第一章主要介绍了Java语言的基础知识,包括基本数据类型及运算、流程控制语句、字符串、数组、类与对象、继承、接口、异常以及Java与指针的概念。这些内容是学习Java语言和后续数据结构的基础,理解了Java的基础特性...
二进制基础是指Java语言中的二进制数系统,包括二进制数、十六进制数、八进制数等。 2.16 Java基础其他注意事项 Java基础其他注意事项包括Java语言的历史、Java语言的特点、Java语言的应用等。
Java中的二分搜索算法是一种高效的查找方法,尤其适用于已排序的数组。在本文中,我们将深入探讨二分搜索算法的概念,以及如何在Java中实现它。这个特定的Java程序展示了如何在一个长整型数组中使用递归二分搜索算法...
在 Java 中,二维数组是一种特殊的数组,用于存储矩阵数据。例如: ```java int[][] array = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; ``` 11. 构造代码块 在 Java 中,构造代码块是一种特殊的代码块,用于在对象创建...
在编程领域,数组是一种基本的数据结构,用于存储同类型元素的集合。在处理数组时,我们经常遇到需要处理数组中相同数值的问题。标题"解决数组中出现相同数的情况"指向了一个编程挑战,即如何有效地识别并操作数组中...
在Java编程语言中,基数排序(Radix Sort)是一种非比较型整数排序算法,它通过将数字按位分组并根据每个位上的值进行排序来实现数组的排序。这种算法特别适合处理大量整数,并且可以达到线性时间复杂度O(nk),其中n...
在具体的数据结构实现方面,线性表是基础数据结构之一,书中介绍了线性表的顺序存储与链式存储实现,其中链式存储进一步细分为单链表和双向链表的实现。通过对比顺序存储和链式存储两种方式,使得读者可以更好地理解...
在IT行业中,表排序、索引使用以及使用plist文件存储数据是常见的操作,尤其是在数据库管理和移动应用开发中。下面将详细讲解这三个知识点。 首先,**表排序**是数据处理的基础,无论是在关系型数据库中还是在内存...
- **基本数据类型及运算**:介绍Java中的基本数据类型如整型(`int`, `long`)、浮点型(`float`, `double`)、字符型(`char`)等,以及它们之间的基本运算规则。 - **流程控制语句**:包括条件语句(`if-else`)...
第一章主要介绍了Java语言基础知识,包括基本数据类型、运算、流程控制语句、字符串、数组等,同时详细讨论了Java的面向对象特性,例如类与对象、继承、接口以及异常处理和Java与指针的概念。 第二章介绍了数据结构...
数组作为同类型数据的集合,在Java中被广泛使用。面向对象的特性包括类与对象的定义、继承、接口实现以及异常处理机制。Java不使用传统意义上的指针概念,而是通过引用传递实现间接访问。 数据结构与算法基础: ...
- 线性表的ADT定义了添加、删除、查询等基本操作。 - **3.2 线性表的顺序存储与实现** - 顺序存储是将线性表中的元素存放在连续的内存空间中。 - 实现时需要考虑数组的长度限制和动态扩展等问题。 - **3.3 ...