数据结构是底层组织和储存数据的一种方式,是指数据之间以什么方式排列的。
特征:先进后出,后进先出
类似枪的子弹夹,压在弹夹底部的子弹会最后才发射。进出都在栈首
特征:先进先出,后进后出
类似水管,先流进去的水会被首先流出来。进数据为队首,出队为队尾。
通过索引查找数据
数组因为有索引,所以查询比较快,删除和插入效率较低
链表类似角色游戏的剧情一样,上一个任务完成了就会指向下一个。下面是链表的结构:
完整的链表示意图:
向列表中插入数据:
较为复杂的双向链表,不但保存下一个数据的地址还保存了上一个数据的地址:
特征:
字面意思就是分为两个叉的树,事实上就是类似这样的结构 。一个节点,然后下面分出两个子节点,两个子节点在各自分出两个子节点,以此类推。
结构图:
特点:
按照节点左边小于等于父节点右边大于父节点的规则来存储顺序,便于查找和排序。下面创建一个二叉树,每个叶子包括上节点,左节点,右节点和数据。
// 二叉树的示例
public class Leaf {
private int data;
private Leaf top;
private Leaf left;
private Leaf right;
public Leaf() {
}
public Leaf(int data) {
this.data = data;
}
// get and set
}
public class LeafTest {
public static void main(String[] args) {
Leaf superLeaf = null;
int[] x = {56, 86, 8, 95, 45, 34, 19, 20};
for (int i = 0; i < x.length; i++) {
if (i == 0) {
superLeaf = new Leaf(x[i]);
} else {
addLeaf(superLeaf, x[i]);
}
}
System.out.println(superLeaf);
}
public static void addLeaf(Leaf leaf, int data) {
if (leaf != null) {
int superData = leaf.getData();
if (data <= superData) {
if (leaf.getLeft() == null) {
leaf.setLeft(new Leaf(data));
} else {
addLeaf(leaf.getLeft(), data);
}
} else {
if (leaf.getRight() == null) {
leaf.setRight(new Leaf(data));
} else {
addLeaf(leaf.getRight(), data);
}
}
}
}
}
// 查询二叉树
public class LeafSearch {
public static int x = -1;
public static void main(String[] args) {
int[] array = {56, 86, 8, 95, 45, 34, 19, 20};
Leaf leaf = LeafTest.getLeaf(array);
searchIndex(leaf, 8);
System.out.println(x);
}
private static void searchIndex(Leaf leaf, int i) {
if (leaf != null) {
int data = leaf.getData();
if (data == i) {
x = leaf.getIndex();
} else if (data < i) {
searchIndex(leaf.getRight(), i);
} else if (data > i) {
searchIndex(leaf.getLeft(), i);
}
} else {
x = -1;
}
}
}
以上是个简单的示例,实际二叉树只是比较广,完全二叉树,满二叉树,平衡二叉树和红黑树等等。以后将详细开个系列讲解。
是从JDK1.5之后引入的特性,可以在编译阶段进行类型约束,并进行检查。泛型只支持引用类型,集合体系所有的接口和实现类都支持泛型。
泛型可以放在类、方法和接口上。
// 格式,T只是泛型标识符,可以是任意表示,常见:T,K,V,E
修饰符 class 类名<T>{}
// 示例
public class MyArrayList<T> {
private ArrayList list = new ArrayList();
public void add(T t) {
list.add(t);
}
public void remove(T t) {
list.remove(t);
}
}
public class Demo {
public static void main(String[] args) {
MyArrayList<String> myArrayList = new MyArrayList<>();
myArrayList.add("一");
myArrayList.add("二");
}
}
泛型方法用在方法上,便于通用方法的创建。泛型用在方法上,这样就可以接收任何类型,方法便具备通用型。
// 格式
修饰符 <泛型> 返回类型 方法名(形参列表){}
public class MyFunction {
public static <T> void print(T t) {
System.out.println(t);
}
}
public static void functionTest() {
MyFunction.print("你好!");
MyFunction.print(3.14);
}
// 格式
修饰符 interface 接口类名称<泛型变量>{}
public interface MyInterface<E> {
void println(E e);
}
public class MyInterfaceImpl<E> implements MyInterface<E> {
@Override
public void println(E e) {
System.out.println(e);
}
}
public static void interfaceTest() {
MyInterfaceImpl<String> myInterface = new MyInterfaceImpl<>();
// 此时只能传递String类型
myInterface.println("haha");
MyInterfaceImpl<Integer> myInterface1 = new MyInterfaceImpl<>();
// 此时只能传递Integer类型
myInterface1.println(11);
}
泛型通配符?,?可以通配任何类型,在使用时有以下两种情况:
// 示例
public class GenericImpl<E> {
public void getSize(Collection<? extends E> collection) {
System.out.println(collection.size());
}
}
public static void test() {
GenericImpl<Object> generic = new GenericImpl<>();
List<Object> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
generic.getSize(list);
}
可变参主要用在形参中,可以接收多个参数,它本质是数组。可变参数传递参数比较灵活
,可以不传,一个,多个或数组。使用主要有以下特征:
// 格式
类型... 参数名称
private static void paramTest(String... strings) {
for (int i = 0; i < strings.length; i++) {
System.out.println(strings[i]);
}
}
paramTest();
paramTest("asas");
paramTest("sa", "as");
String[] x = {"1", "2"};
paramTest(x);
本章结束,用于个人学习和小白入门,大佬勿喷!希望大家多多点赞收藏支撑支撑!
源码 【GitHub】 【码云】