1. 什么是单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素
结点结构 ┌───┬───┐ │data │next │ └───┴───┘ data域–存放结点值的数据域 next域–存放结点的直接后继的地址(位置)的指针域(链域) 链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,每个结点只有一个链域的链表称为单链表(Single Linked List)。
头指针head和终端结点 单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。链表由头指针唯一确定,单链表可以用头指针的名字来命名。 终端结点无后继,故终端结点的指针域为空,即NULL。
注意事项:
我们认为当节点的next域为空时,单链表就结束了head节点是不允许被改变的,所以我们如果需要使用,就需要使用一个临时变量来代替head头结点
2.创建一个单链表的节点的类(注意,这里不是单链表,这里指的是他的每一个节点)
no name nickName 指的就是节点的data域next我们乍一看这是一个对象,但是他指向了我们的下一个节点的位置,下面我会向大家解释
class HerNode{
public int no
;
public String name
;
public String nickName
;
public HerNode next
;
public HerNode(int no
, String name
, String nickName
) {
this.no
= no
;
this.name
= name
;
this.nickName
= nickName
;
}
@Override
public String
toString() {
return "HerNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
", nickName='" + nickName
+ '\'' +
'}';
}
}
3.创建一个管理整合类,把节点整合为单链表
3.1将节点插入到单链表中,按照代码顺序插入
头结点永远不能动,所以我们需要创建一个临时变量
class SingleLinkedListDemo{
private HerNode head
= new HerNode(0,"","");
public void add(HerNode herNode
){
HerNode temp
= head
;
while (true){
if (temp
.next
==null
){
break;
}
temp
= temp
.next
;
}
temp
.next
= herNode
;
}
}
3.2创建单链表的遍历方法
这里的next指的是对象
class SingleLinkedListDemo{
public void list(){
if (head
.next
==null
){
System
.out
.println("链表为空");
return;
}
HerNode temp
= head
.next
;
while (true){
if (temp
== null
){
break;
}
System
.out
.println(temp
);
temp
= temp
.next
;
}
}
}
3.3创建单链表并打印
public class SingleLinkedList {
public static void main(String
[] args
) {
HerNode her6
= new HerNode(6, "鲁智深", "花和尚");
HerNode her2
= new HerNode(2, "卢俊义", "玉麒麟");
HerNode her7
= new HerNode(7, "李颖", "天府行");
HerNode her8
= new HerNode(8, "行者", "武松");
SingleLinkedListDemo singleLinkedList
= new SingleLinkedListDemo();
singleLinkedList
.add(her6
);
singleLinkedList
.add(her2
);
singleLinkedList
.add(her7
);
singleLinkedList
.add(her8
);
singleLinkedList
.list();
}
}
这里我们发现了一个问题,他的链表插入是按照我们代码的顺序插入的,并不是按照我们编号的大小进行排序的,我希望我不按照代码顺序插入,而是编号排序
3.4将节点插入到单链表中,按照no顺序插入
class SingleLinkedListDemo{
public void add2(HerNode herNode
){
HerNode temp
= head
;
boolean flag
= false;
while (true){
if(temp
.next
==null
){
break;
}
if (temp
.next
.no
>herNode
.no
){
break;
}else if (temp
.next
.no
==herNode
.no
){
flag
= true;
break;
}
temp
= temp
.next
;
}
if (flag
){
System
.out
.printf("准备插入的编号 %d 已经存在,无法添加\n",herNode
.no
);
}else {
herNode
.next
= temp
.next
;
temp
.next
= herNode
;
}
}
}
3.5创建单链表并打印
public class SingleLinkedList {
public static void main(String
[] args
) {
HerNode her6
= new HerNode(6, "鲁智深", "花和尚");
HerNode her2
= new HerNode(2, "卢俊义", "玉麒麟");
HerNode her7
= new HerNode(7, "李颖", "天府行");
HerNode her8
= new HerNode(8, "行者", "武松");
SingleLinkedListDemo singleLinkedList
= new SingleLinkedListDemo();
singleLinkedList
.add2(her6
);
singleLinkedList
.add2(her2
);
singleLinkedList
.add2(her7
);
singleLinkedList
.add2(her8
);
singleLinkedList
.list();
}
}
3.6修改单链表的某个节点
class SingleLinkedListDemo{
public void update(HerNode newHerNode
){
if (head
.next
== null
){
System
.out
.println("链表为空");
return;
}
HerNode temp
= head
.next
;
boolean flag
= false;
while(true){
if (temp
==null
){
break;
}
if (temp
.no
==newHerNode
.no
){
flag
= true;
break;
}
temp
= temp
.next
;
}
if (flag
= true){
temp
.name
= newHerNode
.name
;
temp
.nickName
= newHerNode
.nickName
;
}else {
System
.out
.printf("没有找到编号等于%d的节点,不能修改\n",newHerNode
.no
);
}
}
}
3.7修改单链表的某个节点数据
System
.out
.println("修改节点信息后");
HerNode newHer2
= new HerNode(2, "卢俊义2", "玉麒麟2");
singleLinkedList2
.update(newHer2
);
singleLinkedList2
.list();
System
.out
.println("=======================================");
3.8删除单链表的节点
class SingleLinkedListDemo{
public void delete(int no
){
HerNode temp
= head
;
boolean flag
= false;
while (true){
if (temp
.next
==null
){
break;
}
if (temp
.next
.no
==no
){
flag
= true;
break;
}
temp
= temp
.next
;
}
if (flag
==true){
temp
.next
= temp
.next
.next
;
}else{
System
.out
.printf("要删除的节点%d不存在\n",no
);
}
}
}
3.9删除单链表的节点
singleLinkedList2
.delete(1);
singleLinkedList2
.list();
System
.out
.println("=======================================");
3.10统计单链表的节点个数(除去+头结点)
public HerNode
getHead() {
return head
;
}
public int getLength(HerNode head
){
if (head
.next
==null
){
return 0;
}
int length
= 0 ;
HerNode cur
= head
.next
;
while(cur
!= null
){
length
++;
cur
= cur
.next
;
}
return length
;
}
3.11测试统计单链表的节点个数(除去+头结点)
HerNode head
= singleLinkedList
.getHead();
System
.out
.println("有效的节点个数"+singleLinkedList
.getLength(head
));
System
.out
.println("==========================");
3.12得到单链表的倒数第k个节点的数据
public HerNode
findLastIndexNode(HerNode head
,int index
){
if (head
.next
==null
){
return null
;
}
int length
= getLength(head
);
if (index
<= 0 || index
> length
){
return null
;
}
HerNode temp
= head
.next
;
for (int i
= 0 ;i
<length
-index
;i
++){
temp
=temp
.next
;
}
return temp
;
}
3.13得到单链表的倒数第1个节点的数据
HerNode lastIndexNode
= singleLinkedList
.findLastIndexNode(head
, 1);
System
.out
.println("倒数节点的数据为:"+lastIndexNode
);
3.14翻转单链表
public void reverseList(HerNode head
){
if(head
.next
==null
||head
.next
.next
==null
){
return;
}
HerNode cur
= head
.next
;
HerNode next
= null
;
HerNode reverseHead
= new HerNode(0,"","");
while (cur
!=null
){
next
= cur
.next
;
cur
.next
= reverseHead
.next
;
reverseHead
.next
= cur
;
cur
= next
;
}
head
.next
=reverseHead
.next
;
}
3.15测试翻转单链表
System
.out
.println("==========================");
System
.out
.println("翻转单链表");
singleLinkedList
.reverseList(head
);
singleLinkedList
.list();
4 整合代码
外加一个使用栈来翻转单链表。这样不会破坏原有链表的结构
import java
.util
.Stack
;
public class SingleLinkedList {
public static void main(String
[] args
) {
HerNode her1
= new HerNode(1, "鲁智深", "花和尚");
HerNode her2
= new HerNode(2, "卢俊义", "玉麒麟");
HerNode her3
= new HerNode(3, "李颖", "天府行");
HerNode her4
= new HerNode(4, "行者", "武松");
HerNode her8
= new HerNode(8, "鲁智深", "花和尚");
HerNode her5
= new HerNode(5, "卢俊义", "玉麒麟");
HerNode her6
= new HerNode(6, "李颖", "天府行");
HerNode her7
= new HerNode(7, "行者", "武松");
SingleLinkedListDemo singleLinkedList
= new SingleLinkedListDemo();
singleLinkedList
.add(her1
);
singleLinkedList
.add(her4
);
singleLinkedList
.add(her2
);
singleLinkedList
.add(her3
);
System
.out
.println("修改前");
singleLinkedList
.list();
System
.out
.println("=======================================");
SingleLinkedListDemo singleLinkedList2
= new SingleLinkedListDemo();
singleLinkedList2
.add2(her8
);
singleLinkedList2
.add2(her5
);
singleLinkedList2
.add2(her6
);
singleLinkedList2
.add2(her7
);
System
.out
.println("修改后");
singleLinkedList2
.list();
System
.out
.println("=======================================");
System
.out
.println("修改节点信息后");
HerNode newHer2
= new HerNode(5, "卢俊义2", "玉麒麟2");
singleLinkedList2
.update(newHer2
);
singleLinkedList2
.list();
System
.out
.println("=======================================");
System
.out
.println("删除节点后");
singleLinkedList
.delete(1);
singleLinkedList
.list();
System
.out
.println("=======================================");
HerNode head
= singleLinkedList
.getHead();
System
.out
.println("有效的节点个数"+singleLinkedList
.getLength(head
));
System
.out
.println("==========================");
HerNode lastIndexNode
= singleLinkedList
.findLastIndexNode(head
, 1);
System
.out
.println("倒数节点的数据为:"+lastIndexNode
);
System
.out
.println("==========================");
System
.out
.println("翻转单链表");
singleLinkedList
.reverseList(head
);
singleLinkedList
.list();
System
.out
.println("==========================");
System
.out
.println("使用stack的方式逆序打印");
singleLinkedList
.reverseStack(head
);
}
}
class SingleLinkedListDemo{
private HerNode head
= new HerNode(0,"","");
public HerNode
getHead() {
return head
;
}
public void add(HerNode herNode
){
HerNode temp
= head
;
while (true){
if (temp
.next
==null
){
break;
}
temp
= temp
.next
;
}
temp
.next
= herNode
;
}
public void add2(HerNode herNode
){
HerNode temp
= head
;
boolean flag
= false;
while (true){
if(temp
.next
==null
){
break;
}
if (temp
.next
.no
>herNode
.no
){
break;
}else if (temp
.next
.no
==herNode
.no
){
flag
= true;
break;
}
temp
= temp
.next
;
}
if (flag
){
System
.out
.printf("准备插入的编号 %d 已经存在,无法添加\n",herNode
.no
);
}else {
herNode
.next
= temp
.next
;
temp
.next
= herNode
;
}
}
public void update(HerNode newHerNode
){
if (head
.next
== null
){
System
.out
.println("链表为空");
return;
}
HerNode temp
= head
.next
;
boolean flag
= false;
while(true){
if (temp
==null
){
break;
}
if (temp
.no
==newHerNode
.no
){
flag
= true;
break;
}
temp
= temp
.next
;
}
if (flag
= true){
temp
.name
= newHerNode
.name
;
temp
.nickName
= newHerNode
.nickName
;
}else {
System
.out
.printf("没有找到编号等于%d的节点,不能修改\n",newHerNode
.no
);
}
}
public void delete(int no
){
HerNode temp
= head
;
boolean flag
= false;
while (true){
if (temp
.next
==null
){
break;
}
if (temp
.next
.no
==no
){
flag
= true;
break;
}
temp
= temp
.next
;
}
if (flag
==true){
temp
.next
= temp
.next
.next
;
}else{
System
.out
.printf("要删除的节点%d不存在\n",no
);
}
}
public void list(){
if (head
.next
==null
){
System
.out
.println("链表为空");
return;
}
HerNode temp
= head
.next
;
while (true){
if (temp
== null
){
break;
}
System
.out
.println(temp
);
temp
= temp
.next
;
}
}
public int getLength(HerNode head
){
if (head
.next
==null
){
return 0;
}
int length
= 0 ;
HerNode cur
= head
.next
;
while(cur
!= null
){
length
++;
cur
= cur
.next
;
}
return length
;
}
public HerNode
findLastIndexNode(HerNode head
,int index
){
if (head
.next
==null
){
return null
;
}
int length
= getLength(head
);
if (index
<= 0 || index
> length
){
return null
;
}
HerNode temp
= head
.next
;
for (int i
= 0 ;i
<length
-index
;i
++){
temp
=temp
.next
;
}
return temp
;
}
public void reverseList(HerNode head
){
if(head
.next
==null
||head
.next
.next
==null
){
return;
}
HerNode cur
= head
.next
;
HerNode next
= null
;
HerNode reverseHead
= new HerNode(0,"","");
while (cur
!=null
){
next
= cur
.next
;
cur
.next
= reverseHead
.next
;
reverseHead
.next
= cur
;
cur
= next
;
}
head
.next
=reverseHead
.next
;
}
public void reverseStack(HerNode head
){
if (head
.next
==null
){
return;
}
Stack
<HerNode> stack
= new Stack<HerNode>();
HerNode cur
= head
.next
;
while (cur
!=null
){
stack
.push(cur
);
cur
= cur
.next
;
}
while (stack
.size()>0){
System
.out
.println(stack
.pop());
}
}
}
class HerNode{
public int no
;
public String name
;
public String nickName
;
public HerNode next
;
public HerNode(int no
, String name
, String nickName
) {
this.no
= no
;
this.name
= name
;
this.nickName
= nickName
;
}
@Override
public String
toString() {
return "HerNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
", nickName='" + nickName
+ '\'' +
'}';
}
}