继上篇文章对顺序表的介绍,这篇文章介绍链表,作为数据结构中最重要的一大模块,链表也是以后常用的
单链表是其中的核心,理解了单链表,其实链表的知识你也就掌握了。
代码附在最后!!!! 思路在程序注释。详解
一。
1.代码部分 一包 三类 节点类,链表类,测试类 在学习过程中可以对着左侧行序号更改代码
2.节点类
3.链表类
4.测试类
5.运行结果:
二。代码附上
Node.java
package LinkList;
/*
* 定义节点类,后续合成链表或者对链表进行操作
* */
public class Node {
//节点储存的变量
public int data;
//指向下一个节点
public Node next = null;
public Node(int data) {
this.data = data;
}
}
LinkedList.java
package LinkList;
/*
* 定义链表模板,将链表对象的增删改查等功能补充完整
* 有时我们会在链表的头节点之前加一个固定的头节点表示开始,其可以用来存储附加信息等
* 这次的demo我们没有使用这种头节点,所以实际实现链表以后,头节点就是真正的数据块节点
* */
public class LinkedList {
//定义链表的头节点,因为链表刚建立是空,所以定义头节点为null
Node head = null;
//给链表添加节点,实质是寻找末尾节点,并将其指向新节点,使新节点的指向为null
public void AddNode(int data) {
Node newNode = new Node(data);
//寻找并定义末尾节点
//若head开始便是空的,则证明是空链表,直接让head指向新插入节点,程序结束
if(head==null) {
head = newNode;
return;
}
//定义末尾节点temp
Node temp = head;
//循环使temp从头走到null,此时temp指向null的节点为末尾节点
while(temp.next!=null) {
temp = temp.next;
}
//将temp指向新插入的节点,如此便实现了链表节点的插入
temp.next=newNode;
}
//删除链表节点,实质是将要删除节点的前节点的next指向删除节点的后节点,从而跳过该节点
public void DeleteNode(int index) {
//判断index是否合法,由此便需要求链表的长度length
if(index<1||index>Length()) {
try {
throw new Exception("此位置不合法,无节点可删除");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//如果删除位置在头节点,故直接让head指向后节点便跳过,不需要执行太多逻辑
if(index == 1) {
head = head.next;
}
//如果删除位置不在头节点,则执行逻辑
//定义两个节点,这两个节点遍历往后走,当后节点到达所要删除的节点的位置时
//将前节点的next指向后节点的next,从而在链表结构中跳过index处的节点,实现删除
Node preNode = head;
Node bacNode = preNode.next;
//定义i计数是否到达index-1处,因为当i到达index-1的前一处时
//preNode到达了index-1,bacNode刚好到达index处,所以使preNode.next = bacNode.next刚好跳过index
int i = 1;
while(i<index-1) {
preNode = preNode.next;
bacNode = bacNode.next;
i++;
}
//到达index处,进行跳过该节点
preNode.next = bacNode.next;
}
//打印list值
public void FindAll() {
Node newNode = head;
//此处是节点是否存在而不是节点指向是否为空
while(newNode!=null) {
System.out.println(newNode.data+" ");
newNode = newNode.next;
}
}
//查询正数某处节点的值
public void FindOne(int index) {
//判断index是否合法
if(index<1||index>Length()) {
return;
}
Node newNode = head;
for(int i=0;i<index-1;i++) {
newNode = newNode.next;
}
System.out.println("正数所求的值为"+newNode.data);
}
//查询倒数某处节点的值
public void FindBackOne(int index) {
//判断index是否合法
if(index<1||index>Length()) {
return;
}
//定义前后两个节点,相距距离为index,当后节点指向为null的时候,前节点的data为所求的值
Node preNode = head;
Node backNode = preNode;
for(int i=1;i<index;i++) {
backNode = backNode.next;
}
while(backNode.next!=null) {
preNode = preNode.next;
backNode = backNode.next;
}
System.out.println("倒数所求值为"+preNode.data);
}
//求链表的长度
public int Length() {
int length = 0;
//节点从头遍历,直到指向null
//故定义一个节点使其为头节点
Node newNode = head;
//注意是节点不为空,而不是指向不为空
while(newNode!=null) {
length++;
newNode = newNode.next;
}
return length;
}
}
Test.java
package LinkList;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建链表
LinkedList la = new LinkedList();
//链表节点插入
la.AddNode(11);
la.AddNode(22);
la.AddNode(33);
la.AddNode(44);
la.AddNode(55);
//链表删除节点
la.DeleteNode(2);
//正向查找某一结点
la.FindOne(4);
//反向查找某一结点
la.FindBackOne(4);
//打印全部节点data
la.FindAll();
}
}