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 接口,使用 ...
随机推荐
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
传送门&& 原题解 蒟蒻终于做到一道方伯伯的题了…… 调了一个上午一直TLE(发现自己打了好久的splay板子竟然是错的这种丢人事情我就不说了) 很明显,要建两棵树,$T1$维护排名, ...
- scrapy下载中间件,UA池和代理池
一.下载中间件 框架图: 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引擎将请求传递给下载器过程中, 下载中间件可以对请 ...
- PHP实现用户在线状态检测
这个是基于ThinkPHP框架的,其他的可以自己根据需求改 1.先新建一个tags.php文件,放在配置目录Conf下. <?php /* * 添加行为 * */ return arr ...
- UIEvent笔记
UIEvent是什么 代表iOS系统中的一个事件. UIEvent分为三类,touch events, motion events, and remote-control events touch e ...
- 箭头函数中的this和普通函数中的this对比
ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性.下面来总结一下他们之间的区别: 普通函数下的this: 在普通函数中的this总是代表它的直接调用者,在默认情况下,this ...
- jquery实现简易的计算器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- USART列子
#include "stm32f10x.h" void USART_INit(void) { GPIO_InitTypeDef GPIO_Initstructe; USART_In ...
- 采用轮询的方式检测串口输入&&采用中断的方式检测串口输入的区别!
区别1:中断USART1_IRQHandler()不放进main(主函数)里,而轮询检测rcv()需要: 但是需要在主函数里对中断NVIC()进行初始化,因为所有程序都是从主函数开始一步一步执行,想要 ...
- java 的继承
1 为什么要使用继承? 为了提取两个类中公共的代码,可以使用继承抽取重复性的代码到一个公共类中,这个公共的类称为父类(super class).继承于父类的类称为子类(sub class). java ...
- linux 内存介绍
linux用free -m 查看linux内存使用情况 具体参数如下: Mem:内存的使用情况总览表. totel:机器总的物理内存 单位为:M used:用掉的内存. free:空闲的物理内存. 物 ...