上节课已经熟悉了ArrayList的使用,并且进行了简单模拟实现。通过源码知道,ArrayList底层使用数组来存储元素:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// ...
// 默认容量是10
private static final int DEFAULT_CAPACITY = 10;
//...
// 数组:用来存储元素
transient Object[] elementData; // non-private to simplify nested class access
// 有效元素个数
private int size;
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//
}
由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java集合中又引入了LinkedList,即链表结构。
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
package mysingleList;
public interface IList {
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
void addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
void remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int size();
void clear();
void display();
}
public class MySingleList implements IList{
static class ListNode{
public int val;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
public ListNode head;
public void createList(){
ListNode node1 = new ListNode(12);
ListNode node2 = new ListNode(23);
ListNode node3 = new ListNode(34);
ListNode node4 = new ListNode(45);
ListNode node5 = new ListNode(56);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
this.head = node1;
}
开辟了内存空间
使每个node的next域指向下一个节点的地址,连接成链表
head指向第一个节点的地址
public void addFirst(int data) {
ListNode node = new ListNode(data);
if(this.head == null){
this.head = node;
}
else {
node.next = this.head;
this.head = node;
}
}
对 node.next = this.head;
this.head = node;
进行解释,node的next域指向下一个节点的地址
head继续为头节点
public void addLast(int data) {
ListNode node = new ListNode(data);
ListNode cur = head;
if (this.head == null){
this.head = node;
}
else {
while(cur.next != null){
cur = cur.next;
}
cur.next = node;
}
}
找到最后一个元素cur,cur的next指向要插入元素的地址
private ListNode searchPrev(int index){
ListNode cur = this.head;
int count = 0;
while(count != index-1){
cur = cur.next;
count++;
}
return cur;
}
public void addIndex(int index, int data) {
//判断index的位置是否合法
if(index < 0 || index >size()){
return;
}
//插入到第一个节点位置
if(index == 0){
addFirst(data);
}
//插入到最后一个节点的位置
if (index == size()){
addLast(data);
}
//中间位置
else {
ListNode node = new ListNode(data);
ListNode cur = searchPrev(index);
node.next = cur.next;
cur.next = node;
}
}
public boolean contains(int key) {
ListNode cur = this.head;
while(cur != null){
if(cur.val == key){
return true;
}
}
return false;
}
遍历一遍链表寻找是否有key元素
private ListNode findPrev(int key){
ListNode cur = this.head;
while(cur.next != null){
if (cur.next.val == key){
return cur;
}
cur = cur.next;
}
return null;
}
public void remove(int key) {
if (this.head == null){
System.out.println("没有节点,无法删除");
return;
}
//指定元素在头节点
if (this.head.val == key){
this.head = this.head.next;
}
else {
ListNode cur = findPrev(key);
//没有找到指定元素
if (cur == null){
System.out.println("没有找到要删除的节点");
return;
}
//找到了指定元素
ListNode del = cur.next;
cur.next = del.next;
}
}
public void removeAllKey(int key) {
if(this.head == null){
return;
}
ListNode prev = this.head;
ListNode cur = this.head.next;
while(cur != null){
if(cur.val == key){
prev.next = cur.next;
cur = cur.next;
}
else {
prev = cur;
cur = cur.next;
}
}
//删除的节点为头节点
if(this.head.val == key){
this.head = this.head.next;
}
}
public int size() {
ListNode cur = this.head;
int count = 0;
while(cur != null) {
count++;
cur = cur.next;
}
return count;
}
public void clear() {
ListNode cur = this.head;
while(cur != null){
ListNode curNext = cur.next;
cur.next = null;
cur = curNext;
}
head = null;
}
package mysingleList;
public class MySingleList implements IList{
static class ListNode{
public int val;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
public ListNode head;
public void createList(){
ListNode node1 = new ListNode(12);
ListNode node2 = new ListNode(23);
ListNode node3 = new ListNode(34);
ListNode node4 = new ListNode(45);
ListNode node5 = new ListNode(56);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
this.head = node1;
}
@Override
public void addFirst(int data) {
ListNode node = new ListNode(data);
if(this.head == null){
this.head = node;
}
else {
node.next = this.head;
this.head = node;
}
}
@Override
public void addLast(int data) {
ListNode node = new ListNode(data);
ListNode cur = head;
if (this.head == null){
this.head = node;
}
else {
while(cur.next != null){
cur = cur.next;
}
cur.next = node;
}
}
@Override
public void addIndex(int index, int data) {
if(index < 0 || index >size()){
return;
}
if(index == 0){
addFirst(data);
}
if (index == size()){
addLast(data);
}
else {
ListNode node = new ListNode(data);
ListNode cur = searchPrev(index);
node.next = cur.next;
cur.next = node;
}
}
private ListNode searchPrev(int index){
ListNode cur = this.head;
int count = 0;
while(count != index-1){
cur = cur.next;
count++;
}
return cur;
}
@Override
public boolean contains(int key) {
ListNode cur = this.head;
while(cur != null){
if(cur.val == key){
return true;
}
}
return false;
}
@Override
public void remove(int key) {
if (this.head == null){
System.out.println("没有节点,无法删除");
return;
}
if (this.head.val == key){
this.head = this.head.next;
}
else {
ListNode cur = findPrev(key);
if (cur == null){
System.out.println("没有找到要删除的节点");
return;
}
ListNode del = cur.next;
cur.next = del.next;
}
}
private ListNode findPrev(int key){
ListNode cur = this.head;
while(cur.next != null){
if (cur.next.val == key){
return cur;
}
cur = cur.next;
}
return null;
}
@Override
public void removeAllKey(int key) {
if(this.head == null){
return;
}
ListNode prev = this.head;
ListNode cur = this.head.next;
while(cur != null){
if(cur.val == key){
prev.next = cur.next;
cur = cur.next;
}
else {
prev = cur;
cur = cur.next;
}
}
if(this.head.val == key){
this.head = this.head.next;
}
}
@Override
public int size() {
ListNode cur = this.head;
int count = 0;
while(cur != null) {
count++;
cur = cur.next;
}
return count;
}
@Override
public void clear() {
ListNode cur = this.head;
while(cur != null){
ListNode curNext = cur.next;
cur.next = null;
cur = curNext;
}
head = null;
}
@Override
public void display() {
ListNode cur = this.head;
while (cur != null){
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
}