Java基础(十)数据结构
一、数据结构
1、数据结构的定义
数据结构是计算机存储,组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或存储效率。数据结构往往同高效的检索算法和索引技术有关。(来源于百度百科)
2、存储数据的方式
1、变量
变量声明格式: 数据类型 变量名
示例:int age
变量赋值:int age = 22;
注意事项:
- 需要注意值和类型的匹配问题。
- 在使用局部变量之前必须要赋值。
- 成员变量有默认值,但都没有多大意义,在做项目时,要给它赋值。
变量的特点:只能存放一个值。
2、数组
数组的声明格式:数组中元素的类型[] 数组名
示例:int[] ages = new int[3];
数组特点:长度固定,只能存储同种类型数据。
3、自定义类存储
自定义一个可以自动增长,可以存储任意多个 int 元素的数据结构。
实现步骤:
1、自定义一个容器类 intArray。
2、先做到可以储存多个 int 值,内部使用 int 数组。
3、类中创建一个 int 数组,当 int 数组满了之后,创建一个新的数组,并把老的数组中的值拷贝到新的数组中(实现自动扩容)。
具体代码实现:
import java.util.Arrays; /**
* 自定义可以自动扩容的数组
*/
public class IntArray {
private int[] data;
private int index = 0; //构造方法,初始化大小为2
public IntArray() {
this.data = new int[2];
} /**
* 添加数据,自动扩容
* add添加数据的函数
*
* @param i
*/
public void add(int i) {
if (index >= data.length) {
//如果索引大于数组长度,需要新建数组
int[] dataNew = new int[data.length + 2];
System.arraycopy(data, 0, dataNew, 0, data.length); //拷贝数据
data = dataNew;
data[index] = i; //存值
index += 1;
} else {
//如果索引小于数组长度,直接存值
data[index] = i;
index += 1;
}
} /**
* 通过索引删除数据
*
* @param indexId
*/
public void del(int indexId) {
int length = data.length;
System.arraycopy(data, indexId + 1, data, indexId, length - indexId - 1);
} /**
* 通过索引查找元素
*
* @param indexId
*/
public int select(int indexId) {
return data[indexId];
} /**
* 通过索引修改数据
*
* @param indexId
* @param value
*/
public void update(int indexId, int value) {
data[indexId] = value;
} /**
* 返回当前数组长度
*
* @return
*/
public int getLength() {
return data.length;
} /**
* 查找第一个相同元素的索引
*
* @param value
* @return
*/
public Integer queryByValue(int value) {
Integer result = null;
for (int i = 0; i < data.length; i++) {
if (data[i] == value) {
result = i;
}
}
return result;
} //覆写toString方法
@Override
public String toString() {
// TODO Auto-generated method stub
//把元素数组的值,拷贝到新数组里面
int[] newArr = new int[index];
System.arraycopy(data, 0, newArr, 0, index);
return Arrays.toString(newArr);
}
}
测试自定义扩容的数组:
public class TestIntArray {
/**
* 测试自定义的扩容数组
*/
@Test
public void test2(){
IntArray intArray = new IntArray();
intArray.add(11);
intArray.add(22);
intArray.add(33);
intArray.add(44);
intArray.add(55);
//根据索引删除
intArray.del(2);
int select = intArray.select(1);
System.out.println(select);
//更新
intArray.update(1, 2333);
int select1 = intArray.select(1);
System.out.println(select1);
//通过值查询第一个索引
Integer index = intArray.queryByValue(55);
System.out.println("index: " + index);
//返回数组长度
int length = intArray.getLength();
System.out.println("length: " + length);
System.out.println(intArray);
}
}
二、链表
1、链表定义
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。(来源于百度百科)
2、基于类实现链表
1、实现步骤
1、定义容器类。
2、定义Node(口袋类),类里面定义两个字段,一个Object类型存放值,一个Node类型字段,存放下一个值。
3、在容器里面有个字段,在容器类里面还应该提供添加、查找、删除方法。
自定义Node类的代码:
/**
* 自定义Node类
*/
public class Node {
// 存放值
private Object value;
//存放下一个值
private Node next; public Node() { } public Node(Object value) {
this.value = value;
} public Object getValue() {
return value;
} public void setValue(Object value) {
this.value = value;
} public Node getNext() {
return next;
} public void setNext(Node next) {
this.next = next;
}
}
具体实现链表代码:
/**
* 实现链表
*/
public class LinkList {
private Node first;
private int size; //链表大小,默认值为0 /**
* 添加节点的方法
*
* @param obj
*/
public void add(Object obj) {
//1、把用户传入的数据打包
Node node = new Node(obj); //2、把打包好的数据挂在first上面
if (first == null) {
//如果是第一次添加,直接挂在first上面
first = node;
} else {
Node temp = first;
//不是第一次添加,寻找最后一个节点,挂在上面
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(node);
}
size++;
} public Node getFirst() {
return first;
} public void setFirst(Node first) {
this.first = first;
} public int getSize() {
return size;
} public void setSize(int size) {
this.size = size;
} //覆写toString方法
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("[");
Node temp = first; //使用一个临时变量存储
if (temp != null) {
//当为第一个元素的时候
if (temp.getNext() == null) {
//没有下一个节点
stringBuffer.append(temp.getValue());
} else {
stringBuffer.append(temp.getValue()).append(",");
}
} while (temp.getNext() != null) {
//指针向下移动一个位置
temp = temp.getNext();
if (temp.getNext() == null) {
//最后一个节点
stringBuffer.append(temp.getValue());
} else {
stringBuffer.append(temp.getValue()).append(",");
}
}
stringBuffer.append("]");
return stringBuffer.toString();
}
}
测试链表:
import org.junit.Test;
public class TestLink {
/**
* 测试链表
*/
@Test
public void testLink() {
LinkList linkList = new LinkList();
linkList.add(11);
linkList.add(22);
linkList.add(33);
linkList.add(44);
linkList.add(55);
linkList.add(66);
int size = linkList.getSize();
System.out.println("size: " + size); //size: 6
System.out.println(linkList); //[11,22,33,44,55,66]
}
}
Java基础(十)数据结构的更多相关文章
- Java基础十二--多态是成员的特点
Java基础十二--多态是成员的特点 一.特点 1,成员变量. 编译和运行都参考等号的左边. 覆盖只发生在函数上,和变量没关系. Fu f = new Zi();System.out.println( ...
- Java基础十--接口
Java基础十--接口 一.接口的定义和实例 /* abstract class AbsDemo { abstract void show1(); abstract void show2(); } 8 ...
- Java基础(十二)--clone()方法
Clone在Java中就是用来复制对象,通过分配一个和源对象相同大小的内存空间,然后创建一个新的对象,那么他和=的区别在哪? 通过=实现对象拷贝: @Data @NoArgsConstructor @ ...
- java基础(十六)----- equals()与hashCode()方法详解 —— 面试必问
本文将详解 equals()与hashCode()方法 概述 java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) publi ...
- java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的
本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...
- JAVA基础之——数据结构
JAVA数据结构有8种,如下所示,本文从使用场景,优缺点方面讲解. 1 数组Array ArrayList 使用场景:有序的存储同一类型数据的集合,固定大小 优点:通过索引查找方便 缺点:插入或删除一 ...
- java基础十[包、Jar存档文件和部署](阅读Head First Java记录)
将Java的class文件生成为可执行的Java应用程序.Java应用程序有三种:完全在本机执行的Jar(例如本机的GUI可执行程序):完全在服务器端远程执行的(例如浏览器来进行存取):介于两者之间的 ...
- 黑马程序员 Java基础<十八>---> 网路编程
--------------- ASP.Net+Android+IO开发S..Net培训.期待与您交流! --------------- 第一 概述 一.概述: 1.网络模型:OSI参考模型和TCP ...
- java基础(十八)----- java动态代理原理源码解析
关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 静态代理 1.静态代理 静态代理:由程序员创建或特定工 ...
- java基础(十)-----Java 序列化的高级认识
将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用 ...
随机推荐
- “全栈2019”Java第三十八章:类与方法
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 卸载jdk1.7
卸载jdk1.7: 1.开始->程序->控制面板 ->卸载程序->程序和功能 2.找到jdk的两个程序:java 7 update 45和java(TM)SE Developm ...
- 跟刘欣学习造spring
1: 读取配置文件并获取对象实例
- 线上CPU100%?看看这篇是怎么排查的!
前言 作为后端开发工程师,当收到线上服务器CPU负载过高告警时,你会这么做?重启服务,忽略告警?不过在我看来一个合格的工程师是一定要定位到具体问题所在的,从而 fix 它.下面记录一下线上服务器 CP ...
- c 调用 lua 向lua函数 传递table
参考 https://www.myvoipapp.com/blogs/yxh/2016/07/14/c%E5%90%91lua%E5%87%BD%E6%95%B0%E4%BC%A0%E9%80%92t ...
- Linux-Web应用服务性能测试初探
一.服务端与客户端的准备工作 对于服务器最想要的数据就是,每秒支持的并发数,以及相应的内存CPU使用情况. 服务端需要设置最大打开描述符的限制(以支持创建大量的socket),配置socket参数.客 ...
- CRS无法随操作系统自动启动
1.环境说明 一套RedHat7.5上安装的11.2.0.4 RAC,进行正常的系统维护,重启主机后发现GI集群一直无法启动. 2.问题分析 (1).查看GI集群的OHASD进程的日志,发现操作系 ...
- HDU 5442 后缀自动机(从环字符串选定一个位置 , 时针或顺时针走一遍,希望得到字典序最大)
http://acm.hdu.edu.cn/showproblem.php?pid=5442 题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样 ...
- ionic3 引入第三方库(jquery)
安装 npm install jquery npm install @types/jquery 在需要的ts文件中引入,一定要在最顶端 import * as $ from '../../../nod ...
- cuda9.0 中不存在libnppi.so
编译一个caffe版本,报错找不到 -lnppi 发现使用打是cuda9.0, 但是cuda9.0 中不存在libnppi.so. 只好换成cuda8.0.