java数据结构之链表
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的。
先看一下顺序表:
链表是由一个一个的节点组成,那他是怎么链接的呢??
所以链表是由两个部分组成,一部分由存放的内容(val)组成,一部分存放的是下一个节点的引用(地址)(next)
其中head是头节点,是不可以移动的,最后一个节点(尾结点)的next部分为null
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
单向、双向
带头、不带头
循环、非循环
打印单链表
我们主要学习单向,不带头,非循环,和不带头,双向,循环链表
//打印单链表
public void display(){
ListNode cur = this.head;
while (cur != null){
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
查找是否包含关键字key是否在单链表当中![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4003c508d7d7eb322260b9b3d67f5720.png)
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = this.head;
if(cur == null){
System.out.println("链表为空");
}
while(cur != null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
}
头插法
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data);//头插就要拿data实例化一个节点
node.next = head;
head = node;
}
尾插也是差不多的
//删除第一次出现关键字为key的节点
//找到你要删除key的前驱节点
public ListNode zhaopianqu(int key){
ListNode cur = this.head;
while(cur.next != null){
if(cur.next.val == key){
return cur;
}
cur = cur.next;
}
return null;
}
//删除第一次出现关键字为key的节点
public void remove(int key){
if(this.head == null){
System.out.println("链表为空");
return;
}
if(this.head.val == key){
//判断头节点是否为要删除的数据
this.head = this.head.next;
return;
}
ListNode cur = zhaopianqu(key);//找到你要删除key的前驱节点cur
if(cur == null){
System.out.println("没有你要删除的数");
return;
}
ListNode del = cur.next;//del为要删除的key的节点
cur.next = del.next;
}
链表的实现:
class ListNode{
public int val;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
//这是单链表
public class MyListdate {
public ListNode head;//这是头结点
public void contsd(){
//创建节点
ListNode listNode1 = new ListNode(11);
ListNode listNode2 = new ListNode(22);
ListNode listNode3 = new ListNode(33);
ListNode listNode4 = new ListNode(44);
ListNode listNode5 = new ListNode(55);
listNode1.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
listNode4.next = listNode5;
this.head = listNode1;
}
//打印单链表
public void display(){
ListNode cur = this.head;
while (cur != null){
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
//求链表的长度
public int size(){
ListNode cur = this.head;
int cont = 0;
while(cur != null){
cont++;
cur = cur.next;
}
return cont;
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = this.head;
if(cur == null){
System.out.println("链表为空");
}
while(cur != null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
}
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data);//头插就要拿data实例化一个节点
node.next = head;
head = node;
}
//尾插法
public void addLast(int data){
ListNode last = new ListNode(data);
ListNode cur = this.head;
if(cur == null){
head = last;
}else{
while (cur.next != null){
cur = cur.next;
}
cur.next = last;
}
}
//找到你要删除key的前驱节点
public ListNode zhaopianqu(int key){
ListNode cur = this.head;
while(cur.next != null){
if(cur.next.val == key){
return cur;
}
cur = cur.next;
}
return null;
}
//删除第一次出现关键字为key的节点
public void remove(int key){
if(this.head == null){
System.out.println("链表为空");
return;
}
if(this.head.val == key){
//判断头节点是否为要删除的数据
this.head = this.head.next;
return;
}
ListNode cur = zhaopianqu(key);//找到你要删除key的前驱节点cur
if(cur == null){
System.out.println("没有你要删除的数");
return;
}
ListNode del = cur.next;//del为要删除的key的节点
cur.next = del.next;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
ListNode node = new ListNode(data);
ListNode cur = this.head;
if(index == 0){ //如果原始链表长度为0,那就是头插
addFirst(data);
return;
}
if(index == size()){ //如果链表长度和index相等那就是尾插
addLast(data);
return;
}
while(index-1 != 0){ //在index位置插 cur就走index-1 歩cur记录cur.next的值
cur = cur.next;
index--;
}
node.next = cur.next;
cur.next = node;
}
//删除所有值为key的节点
public void removeAllKey(int key) {
if (this.head == null) {
return;
}
ListNode prev = this.head;
ListNode cur = this.head.next;//cur表示要删除的数据的节点
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 void clear(){
while(this.head != null){
ListNode cutNext = head.next;
this.head.next =null;
this.head = cutNext;
}
}
}