一、线性表
1.1顺序表
顺序表在计算机内存中以数组的形式保存线性表,线性表的顺序存储是指用一组地址连续的存储单元,依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。
ArrayList
1.底层使用数组来实现
1.2链表
单链表:
package linear;
import java.util.Iterator;
public class LinkList<T> implements Iterable<T>{
public static void main(String[] args) {
LinkList<String> list = new LinkList<>();
list.insert("你好");
list.insert(1,"嗨");
list.insert(2,"宝宝");
list.insert(3,"臭臭");
// System.out.println(list.get(0));
// System.out.println(list.get(1));
for (String s : list) {
System.out.println(s);
}
System.out.println(list.length());
System.out.println("---------get测试--------");
System.out.println(list.get(2));
System.out.println("---------remove--------");
System.out.println(list.remove(3));
System.out.println("---------------");
for (String s : list) {
System.out.println(s);
}
}
//记录头结点
private Node head;
//记录链表的长度
private int N;
//构造方法
public LinkList(){
head = new Node(null,null);
N = 0;
}
//1.空置线性表
public void clear(){
head.next = null;
head.item = null;
N = 0;
}
//2.判断线性表是否为空,是返回true,否则返回false
public boolean isEmpty(){
return N==0;
}
//3.获取线性表中元素的个数
public int length() {
return N;
}
//4.读取并返回线性表中的第i个元素的值
public T get(int i) {
if (i < 0 || i>= N) {
throw new RuntimeException("位置不合法");
}
Node cur = head.next;
for (int j = 0;j <= i-1;j++) {
cur = cur.next;
}
return cur.item;
}
//5.往线性表中添加一个元素
public void insert(T t) {
Node cur = head;
while (cur.next != null) {
cur = cur.next;
}
Node newNode = new Node(t,null);
cur.next = newNode;
N++;
}
//6.向指定位置i处添加元素t
public void insert(int i,T t) {
// if (i<0 || i >= N) {
// throw new RuntimeException("位置不合法");
// }
//位置i之前的结点
Node pre = head;
for (int j = 0;j <= i-1;j++) {
pre = pre.next;
}
//位置i的结点
Node curr = pre.next;
//构建新的结点,新结点指向位置i的结点
Node newNode = new Node(t,curr);
//之前的结点指向新结点
pre.next = newNode;
//长度+1
N++;
}
//7.删除指定位置i处的元素,并返回删除的元素
public T remove(int i) {
// if (i < 0 || i >= N) {
// throw new RuntimeException("没有指定元素");
// }
Node pre = head;
for (int j = 0;j < i;j++) {
pre = pre.next;
}
Node cur = pre.next;
Node next = cur.next;
pre.next = next;
N--;
return cur.item;
}
//元素t在链表中第一次出现的位置
public int indexOf(T t) {
Node node = head;
for (int i = 0;node.next != null;i++) {
node = node.next;
if (node.item.equals(t)) {
return i;
}
}
return -1;
}
@Override
public Iterator<T> iterator() {
return new LIterator() {
};
}
private class LIterator implements Iterator<T> {
private Node node;
public LIterator() {
this.node = head;
}
@Override
public boolean hasNext() {
return node.next != null;
}
@Override
public T next() {
node = node.next;
return node.item;
}
}
//结点类
private class Node{
T item;
Node next;
public Node(T item,Node next) {
this.item = item;
this.next = next;
}
}
}
双向链表
多个结点组成,每个结点都由一个数据域和两个指针域组成,数据域用来存储数据,两个指针域,其中一个指针域用来指向其后继结点,另一个指针域用来指向前驱结点。
其中链表的头结点的数据域不存储数据,指向前驱节点的指针域为null,指向后继结点的指针域指向第一个真正存储数据的结点。