java数据结构与算法之数组篇
2017-10-17 00:00
411 查看
数据结构和算法的概述
数据结构对计算机内存中的数据的一种安排。
常见数据结构
数据结构 | 优点 | 缺点 |
---|---|---|
数组 | 插入快(根据下标) | 查找慢,删除慢,大小固定 |
有序数组 | 比无序数组查找快 | 删除和插入慢,大小固定 |
栈 | 提供后进先出的存取方式 | 存取其他项很慢 |
队列 | 提供先进先出的存取方式 | 存取其他项很慢 |
链表 | 插入快 删除快 | 查找慢 |
二叉树 | 插入 查找删除都快(树平衡的情况下) | 删除算法比较复杂 |
红黑树(平衡树) | 插入 查找删除都快 | 算法复杂 |
2-3-4树(平衡树) | 插入 查找删除都快 | 算法复杂 |
哈希表 | 插入快,通过关键字存取快(key/value) | 删除慢 |
堆 | 插入 删除快,对最大数据项存取快 | 对其他数据项存取慢 |
图 | 对现实世界建模 | 有些算法慢且复杂 |
对结构中的数据进行各种处理
常见算法
插入排序,简单排序,选择排序,冒泡排序等等
java数据结构与算法之数组
数组介绍数组基本要提供创建,插入,查找,删除功能。
创建的话,在创建的时候需要指定数组大小,创建完毕后,数组大小便为固定。
插入的话,默认是无序的,所以数组元素的顺序是你插入的数据顺序,下标依次增加。
查找的话,如果你知道下标,你可以很快的查询到,如果根据value的话,你需要遍历整个数组,如果你要查询的元素在第一个,则查找一次即可,如果在末尾则需要查找数组大小的次数。
删除的话,你首先需要进行查找,定位到元素,然后进行删除,如果你删除的是第一个元素,在删除完毕之后,会对数组进行移动,把删除位置之后的元素统一往前移动。
java中数组的例子
java版的简单数组实现
package com.arithmetic.array; import java.util.Arrays; /** * Created by bgt on 2017/10/15. * 简单的数组java实现 * 主要是java版本的基础版 */ public class SimpleArray { private int[] arr;//数组对象 /** * 初始化数组大小和实例 * @param size */ public SimpleArray(int size) { this.arr = new int[size]; } /**设置元素*/ public void setElement(int index,int val){ arr[index]=val; } /**获取元素*/ public int getElement(int index){ return arr[index]; } @Override public String toString() { return "SimpleArray{" + "arr=" + Arrays.toString(arr) + '}'; } /** * 使用示例 * @param args */ public static void main(String[] args) { SimpleArray array=new SimpleArray(10); array.setElement(0,22); array.setElement(1,26); array.setElement(2,20); array.setElement(3,28); array.setElement(4,21); System.out.println(array.getElement(4)); } }
java版的高级数组实现
package com.arithmetic.array; /** * Created by bgt on 2017/10/15. * 高级数组 * 包含插入 查找 删除 显示 */ public class SeniorArray { private int[] arr;//具体数组类型 private int totalsize;//已有数组数量 /** * 创建数组实例,并设置大小 * @param size */ public SeniorArray(int size) { this.arr = new int[size]; this.totalsize=0; } /** * 添加数组元素 * @param val */ public void insert(int val){ arr[totalsize++]=val; } /** * 删除数组元素 * @param val */ public void del(int val){ int delindex=findIndex(val); if (delindex<totalsize) { for (int i = delindex; i < totalsize; i++) { arr[i]=arr[i+1]; } totalsize--; } } /** * 查找数组元素 * @param val */ public int findIndex(int val){ int searchIndex=totalsize;//默认是元素数量 for (int i = 0; i < arr.length; i++) { if (arr[i]==val) { searchIndex=i; break; } } System.out.println("val:"+val+",index:"+searchIndex); return searchIndex; } /** * 查找数组元素 * @param index */ public int findByIndex(int index){ return arr[index++]; } /** * 遍历 数组元素 */ public void display(){ for (int i=0;i<totalsize;i++) { System.out.print(arr[i]+","); } System.out.println("----------------------------------"); } public static void main(String[] args) { SeniorArray seniorArray=new SeniorArray(10); seniorArray.insert(2); seniorArray.insert(5); seniorArray.insert(3); seniorArray.insert(1); seniorArray.insert(42); seniorArray.insert(6); System.out.println(seniorArray.totalsize); seniorArray.display(); seniorArray.del(1); seniorArray.display(); } }
有序数组以及线性查找和二分查找比较
有序数组
优点查找速度比无序数组快多了
缺点
插入时要按排序方式把后边的数据进行移动。
与无序数组共同的缺点
删除数据时必须把后边的数据向前移动来填充删除项的空缺。
有序数组Java实现
ArrayInterface.javapackage com.arithmetic.array; import java.util.Arrays; /** * Created by baiguantao on 2017/10/17. */ public interface ArrayInterface { void insert(int val);//插入 int find(int val);//查找 int size();//已有元素数量 void del(int val);//删除 /** * 默认显示array方法 * @param arr */ default void displayAll(int[] arr){ int total=size(); Arrays.stream(arr).limit(total).forEach(a->{ System.out.println(a); }); } }
OrderArray.java
package com.arithmetic.array; /** * Created by baiguantao on 2017/10/17. * 有序数组 */ public class OrderArray implements ArrayInterface{ public int[] arr; public int size;//已有元素数量 public OrderArray(int maxsize) { this.arr = new int[maxsize]; size=0; } /** * 这里是有序数组 * 线性查找示例 * 找到当前元素适合插入的问题 * 随后对元素进行移动操作 * @param val */ @Override public void insert(int val) { //查找适合的位置 int realpostion=0; for (realpostion=0;realpostion<size;realpostion++) { if(arr[realpostion]>val)break;//如果当前元素比val大,则终止循环(这里默认是有序递增形式数组) } //进行元素置换 k是元素数量 比下标错开1位 下标从0 开始 所以k 其实对应下标+1 这样子 for (int k=size;k>realpostion;k--) { arr[k]=arr[k-1]; } arr[realpostion]=val; size++; } /** * 二分查找 * @param val * @return */ @Override public int find(int val) { int first=0;//二分当前范围的起始位置 int last=size-1;//二分当前范围的结束位置 int mid;//二分当前范围的中间值 while (true){ mid=(first+last)/2; if (arr[mid]==val) {//如果刚好与查找的一致,则返回下标 return mid; }else if (first>last){//未查到则返回数组大小 return size; }else{ //当前值大于中间下标 if (arr[mid]<val) { first=mid+1; }else{ last=mid-1; } } } } @Override public int size() { return size; } /** * 数组删除 并移动数组元素 * @param val */ @Override public void del(int val) { int valindex=find(val); if (valindex==size) {//未查到下标 System.out.println("未查到"); }else{ for (int k=valindex;k<size;k++) {//移动后边数组 arr[k]=arr[k+1]; } size--; System.out.println("查到了,进行数组移动..."); } } static boolean b; public static void main(String[] args) { OrderArray orderArray=new OrderArray(10); orderArray.insert(3); orderArray.insert(6); orderArray.insert(5); orderArray.insert(4); orderArray.insert(1); orderArray.displayAll(orderArray.arr); orderArray.del(4); orderArray.displayAll(orderArray.arr); /* int x=0; if (b) { x=1; }else if (b=false) { x=2; }else if (b) { x=3; }else { x=4; } System.out.println("x:"+x);*/ } }
线性查找
其实我们默认使用的就是线性查找。虽然也可以实现查找,但是时间复杂度是N,相对来说比较耗时。 我们在插入的时候采用线性方式来实现。如下所示:/** * 这里是有序数组 * 线性查找示例 * 找到当前元素适合插入的问题 * 随后对元素进行移动操作 * @param val */ @Override public void insert(int val) { //查找适合的位置 int realpostion=0; for (realpostion=0;realpostion<size;realpostion++) { if(arr[realpostion]>val)break;//如果当前元素比val大,则终止循环(这里默认是有序递增形式数组) } //进行元素置换 k是元素数量 比下标错开1位 下标从0 开始 所以k 其实对应下标+1 这样子 for (int k=size;k>realpostion;k--) { arr[k]=arr[k-1]; } arr[realpostion]=val; size++; }
二分查找
使用二分查找的前提是数据是有序的 我们在查找的方法中用二分查找的方式来实现/** * 二分查找 * @param val * @return */ @Override public int find(int val) { int first=0;//二分当前范围的起始位置 int last=size-1;//二分当前范围的结束位置 int mid;//二分当前范围的中间值 while (true){ mid=(first+last)/2; if (arr[mid]==val) {//如果刚好与查找的一致,则返回下标 return mid; }else if (first>last){//未查到则返回数组大小 return size; }else{ //当前值大于中间下标 if (arr[mid]<val) { first=mid+1; }else{ last=mid-1; } } } }
二分查找比较次数
数据量 | 比较次数 |
---|---|
10 | 1 |
1000 | 7 |
10000 | 10 |
10000 | 14 |
100000 | 17 |
1000000 | 20 |
10000000 | 24 |
100000000 | 27 |
1000000000 | 30 |
后记
后续会继续堆栈链表哈希树等的示例。不对之处望大家指正。ricky 20171017
交流群:244930845
相关文章推荐
- Java数据结构与算法之Array数组
- Java数据结构与算法-数组
- java常用的数组、字符串、集合操作以及数据结构与算法基本知识
- java数据结构与算法之数组篇
- Java数据结构与算法(一)-数组
- Java数据结构与算法---数组逆转
- java数据结构与算法(一)----数组简单排序
- Java数据结构与算法之数组(二)
- Java数据结构与算法 - 数组
- Java数据结构与算法之数组
- Java数据结构与算法之数组排序——插入
- Java数据结构与算法之数组排序——冒泡
- java数据结构与算法-有序数组二分查找
- Java数据结构与算法之有序数组的插入和合并
- java数据结构与算法 第2章 数组
- Java数据结构与算法之数组应用——用户登陆与注册数组实现
- java数据结构与算法之双向循环队列的数组实现方法
- <一>java数据结构与算法 数组
- 16、StringBuffer类与包装类、java数组
- Java之数组的拷贝