数据结构与算法-链表实现
链表特点
- 链表以节点的方式来存储
- 链表中存在data域(前一个节点指向data),next域(此节点指向后一个节点)
- 各个节点的物理位置不一定是连续的
- 链表分为带头节点和没有头节点的链表
单向链表(带头节点)
头节点head,不存放具体数据
代码实例:
package com.liulin.linkedlist;
import jdk.nashorn.internal.ir.WhileNode;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add(new HeroMan(1,"刘备","仁德义枪"));
linkedList.add(new HeroMan(2,"关羽","御马高手"));
linkedList.add(new HeroMan(3,"项羽","可辅可坦"));
linkedList.add(new HeroMan(4,"妲己","草丛三婊"));
linkedList.list();
}
}
class LinkedList{
//创建头节点
private HeroMan head = new HeroMan(0,"","");
//链表添加元素
public void add(HeroMan heroMan){
//创建一个辅助节点temp,便于循环
HeroMan temp = head;
//循环链表,找到最后一个元素,naexCode为null则为最后一个元素
while (true){
if (temp.getNextCode() == null){
break;
}
//辅助节点后移,直到找到最后一个节点,循环退出
temp = temp.getNextCode();
}
//循环结束,此时temp为链表最后一个元素,设置其nextCode指向添加进来的元素
temp.setNextCode(heroMan);
}
//遍历链表
public void list(){
//创建一个辅助节点temp,便于循环
HeroMan temp = head.getNextCode();
while (true){
if (temp == null){
break;
}
System.out.println(temp);
//temp节点后移,指向下一个
temp = temp.getNextCode();
}
}
}
class HeroMan{
private int node;
private String name;
private String hashName;
private HeroMan nextCode;
public HeroMan(int node, String name, String hashName){
this.node = node;
this.name = name;
this.hashName = hashName;
}
@Override
public String toString() {
return "HeroMan{" +
"node=" + node +
", name='" + name + '\'' +
", hashName='" + hashName + '\'' +
'}';
}
public HeroMan getNextCode(){
return nextCode;
}
public void setNextCode(HeroMan heroMan){
this.nextCode = heroMan;
}
}
按node顺序添加:
//链表根据node顺序进行添加
public void addByNode(HeroMan heroMan){
//创建辅助节点,便于循环查找
HeroMan temp = head;
//循环找到新节点在链表中的位置
while (true){
//判断此时链表是否是最后一个节点,是则直接退出循环
if (temp.getNextCode() == null){
break;
}
//判断此位置上的node是否相同,节点是否已存在
if(temp.getNode() == heroMan.getNode()){
System.out.println(temp.getNode()+"存在");
throw new RuntimeException("节点已存在!");
}
//找位置,通过判断辅助节点下一个节点的node是否比新节点大
if (temp.getNextCode().getNode() > heroMan.getNode()){
break;
}
temp = temp.getNextCode();
}
//添加链表元素
heroMan.setNextCode(temp.getNextCode());
temp.setNextCode(heroMan);
}
删除代码:
//删除链表某一元素
public void delLinked(int node){
HeroMan temp = head;
while (true){
if (temp.getNextCode() == null){
System.out.println("链表为空或没找到节点");
break;
}
//找到需要删除节点的前一个节点
if (temp.getNextCode().getNode() == node){
temp.setNextCode(temp.getNextCode().getNextCode());
break;
}
temp = temp.getNextCode();
}
}
修改指定节点代码:
//修改链表
public void upsetLinked(HeroMan heroMan){
HeroMan temp = head;
while (true){
if (temp == null){
System.out.println("链表为空或没找到节点");
break;
}
if (temp.getNode() == heroMan.getNode()){
temp.setName(heroMan.getName());
temp.setHashName(heroMan.getHashName());
break;
}
//辅助节点后移
temp = temp.getNextCode();
}
}
反转链表代码:
//反转链表
public void reverseLinked(){
//当前节点的前一个节点
HeroMan pre = null;
//当前节点
HeroMan temp = head.getNextCode();
//当前节点后一个节点
HeroMan next;
//如果链表没有节点,或只有一个节点,不用反转
if (temp == null || temp.getNextCode() == null){
return;
}
//循环到当前节点为null时结束
while (temp != null){
//保留当前节点的下一节点信息
next = temp.getNextCode();
//将当前节点的下一节点指向他的前一节点
temp.setNextCode(pre);
//pre后移
pre = temp;
//temp后移
temp = next;
}
//将头节点后一个节点设置为pre
head.setNextCode(pre);
}