1 链表
1.1 链表的概念及结构
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
之所以叫链表,因为其结构就类似于链条,每个节点包括一个value和指向下一个节点的引用。
1.2 链表的实现
这里主要实现的是不带头的非循环链表
创建节点:
class ListNode1{
public int val;
public ListNode1 next;
//有参构造,给val赋值
public ListNode1(int val){
this.val = val;
}
}
手动创建一个链表:
public class LinkedList {
//链表需要一个head去指向第一个节点
ListNode1 head;
//手动创建一个链表
public void creatList(){
ListNode1 listNode1 = new ListNode1(11);
ListNode1 listNode2 = new ListNode1(22);
ListNode1 listNode3 = new ListNode1(33);
ListNode1 listNode4 = new ListNode1(44);
ListNode1 listNode5 = new ListNode1(55);
head = listNode1;
listNode1.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
listNode4.next = listNode5;
}
}
打印链表:
//打印链表
public void showList(){
ListNode1 cur = head;
if (head == null){ //需要考虑到链表为空的情况
System.out.println("链表为空");
return;
}
while (cur != null){ //这里如果是cur.next!=null,则会将最后一个value漏掉
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
判断链表中是否包含key:
//判断链表中是否包含key
public boolean contain(int key){
ListNode1 cur = head;
while (cur != null){
if (cur.val == key){
return true;
}
cur = cur.next;
}
return false;
}
求链表节点个数:
//求链表节点个数
public int sizeList(){
int count = 0;
ListNode1 cur = head;
while (cur != null){
count++;
cur = cur.next;
}
return count;
}
头插法:
//头插法
public void addFirst(int data){
ListNode1 node1 = new ListNode1(data);
node1.next = head;
head = node1;
}
尾插法:
//尾插法
public void addLast(int data){
ListNode1 node1 = new ListNode1(data);
ListNode1 cur = head;
if(head == null){
addFirst(data);
} else {
while (cur.next != null){
cur = cur.next;
}
cur.next = node1;
}
}
在链表index的位置插入一个节点,假设下表从0开始:
//在链表index的位置插入一个节点,假设下表从0开始
public void addIndex(int index,int data){
ListNode1 node1 = new ListNode1(data);
if (index < 0 || index > sizeList()){
System.out.println("index位置不合法");
return;
}
if (index == 0){
addFirst(data);
return;
}
if (index == sizeList()){
addLast(data);
return;
}
ListNode1 cur = head;
while (index - 1 != 0){ //找到index的前驱节点
cur = cur.next;
index--;
}
node1.next = cur.next;
cur.next = node1;
}
删除第一次值为key的节点:
//删除第一次值为key的节点
public void delKey(int key){
ListNode1 cur = head;
if (cur == null){
System.out.println("链表为空");
return;
}
while (cur.next != null){
if (cur.next.val == key){
cur.next = cur.next.next;
return;
}
cur = cur.next;
}
if (head.val == key){
head = head.next;
return;
}
System.out.println("没有要删除的节点");
}
删除所有值为key的节点:
//删除所有值为key的节点
public void delAllKey(int key){
ListNode1 pre = head;
ListNode1 cur = head.next;
if (cur == null){
System.out.println("链表为空");
return;
}
while (cur != null){
if (cur.val == key){
pre.next = cur.next;
cur = cur.next;
} else {
pre = cur;
cur = cur.next;
}
}
if (head.val == key){ //最后删除头节点为key的节点
head = head.next;
}
}
清空链表:
//清空链表
public void clear(){
ListNode1 curNext ;
while (head != null){ //在清空的时候要提前保存下一个节点的引用
curNext = head;
head = head.next;
curNext.next = null;
}
}