源代码如下:
public class SingleLinklist {
//先初始化一个头结点,不变化,用private
private Heronode head=new Heronode(0,"头结点","");
//添加节点,在尾结点添加,先找到尾结点
public void add(Heronode heronode)
{
//为了找到尾结点,需要遍历,用临时temp
Heronode temp=head;
while(temp.next!=null){
temp=temp.next;
}
temp.next=heronode;
}
//遍历链表
public void list()
{
//先判断是否为空
if(head.next==null)
System.out.println("链表为空");
Heronode temp=head.next;
while(temp.next!=null)
{
System.out.println(temp);
temp=temp.next;
}
System.out.println(temp); //打印尾结点
}
//插入节点,使用临时节点temp找到位置,然后改变next,重复元素不添加
public void insert(Heronode node)
{
Heronode temp=head;
Boolean flag=false; //是否重复
while(true)
{
if(temp.next==null) //空链表
break;
if(temp.next.id>node.id) //位置找到,说明要插入的位置就在temp后面
break;
if(temp.next.id==node.id) {//说明重复了
flag = true;
break;
}
//既不是空链表,又不是重复,但temp.next.id<node.id,说明得往后移
temp=temp.next;
}
if(flag==true)
System.out.println("已经存在");
else
//开始插入,先解决后继节点,在解决前继节点. temp.next
node.next=temp.next;
temp.next=node;
}
public void delete(int no) //根据节点编号删除节点,需要找到待删节点的前一个节点
{
if (head.next == null)
System.out.println("链表为空");
Heronode temp = head; //是head而不是head.next,否则头结点删不到
Boolean flag = false;
while (true) {
if (temp == null) //已经遍历完
break;
if (temp.next.id ==no) { //要找的是待删节点的前一个节点
flag = true;
break;
} else temp = temp.next;
}
if (flag)
{
temp.next=temp.next.next;
}
}
public void update(Heronode node)//根据新节点的编号修改信息
{
if(head.next==null)
System.out.println("链表为空");
Heronode temp=head.next;
Boolean flag=false; //判断是否找到该节点
while(true)
{
if(temp==null) {
System.out.println("已经遍历完");
break;
}
if(temp.id==node.id){
flag=true;
break;
}
else temp=temp.next;
}
if(flag) {
temp.name = node.name;
temp.nickname = node.nickname;
}
else
System.out.println("没找到该节点");
}
}
public int getLength() //获取节点长度,没有统计头结点
{
int length=0;
if(head.next==null)
{
System.out.println("链表为空");
return 0;
}
Heronode temp=head.next;
while(temp!=null) //是否遍历结束,节点为空
{
length++;
temp=temp.next;
}
return length;
}
public Heronode getNode(Heronode head,int index) //获取倒数第K个节点,实际上是遍历第 length-index
{
if(head.next==null)
return null;
int length=getLength();
if(index<=0||index>length) //容错处理
return null;
Heronode temp=head.next;
for(int i=0;i<length-index;i++) //没有等于
{
temp=temp.next;
}
return temp;
}
public void reverse(Heronode head) //单链表反转:头插法,新建一个链表,每遍历原来链表后取下一个节点放在新链表节点的前面
{
if(head.next==null||head .next.next==null) //链表为空或者只有一个节点
{
System.out.println("无需翻转");
}
Heronode temp=head.next; //取下来的节点
Heronode next=null; //指向temp的下一个节点,帮助遍历原来链表
Heronode reverseHead=new Heronode(0,"new head","");//新的头节点
while(temp!=null)
{
next=temp.next; //先保存当前节点的下一个节点,后续需要用它继续遍历
temp.next=reverseHead.next; //同插入的原理,先解决后继关系,在解决前继关系
reverseHead.next=temp;
temp=next; //继续遍历
}
head.next=reverseHead.next; //最后一个节点
}
class Heronode {
public int id;
public String name;
public String nickname;
public Heronode next; //指向下一个节点,next是属性,也是对象
public Heronode(int id, String name, String nickname) {
this.id=id;
this.name=name;
this.nickname=nickname;
}
@Override
public String toString() {
return "Heronode{" +
"id=" + id +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
测试类代码如下
public class SingleLinklistTest {
public static void main(String[] args) {
Heronode hero1=new Heronode(0,"宋江","ss");
Heronode hero2=new Heronode(1,"刘备","ll");
Heronode hero3=new Heronode(3,"关羽","gg");
Heronode hero4=new Heronode(3,"张飞","zz");
//创建链表
SingleLinklist singlelinklist=new SingleLinklist();
singlelinklist.add(hero1); //增
singlelinklist.add(hero3);
singlelinklist.insert(hero2); //插
singlelinklist.list(); //查
singlelinklist.update(hero4); //改
//singlelinklist.list();
singlelinklist.delete(3); //删
singlelinklist.list(); //查
}
}