单向链表java实现
在单链表尾部插入
package linkedlist;
public class SingleLInkedList {
public static void main(String[] args) {
HeroNode h1 = new HeroNode(1,"宋江","rainontime");
HeroNode h2 = new HeroNode(2,"wuyong","cleverman");
HeroNode h3 = new HeroNode(3,"likui","balckHurricane");
SLL s1 = new SLL();
s1.add(h1);
s1.add(h2);
s1.add(h3);
s1.show();
}
}
//定义单链表SingleLinkedList
class SLL{
//初始化头节点,头节点不要动,不用于存放数据
HeroNode head = new HeroNode(0,"","");
//添加节点到单链表
//找到当前链表的最后节点,
//将最后节点的next指向新的节点
public void add(HeroNode heroNode){
HeroNode temp = head;
//遍历链表找到最后,头节点不能动,就创建辅助变量temp
while (true){
if(temp.next == null){
break;
//是最后一个节点,最后一个节点的指针为null,跳出循环
}
temp = temp.next;
//不是最后一个,就将节点向后移
}
temp.next = heroNode;
}
//显示链表,遍历
public void show(){
//判断链表是否为空
//头节点不能动,要辅助变量来帮忙遍历
HeroNode temp = head;
//判断链表是否为空
if (temp.next == null){
System.out.println("链表为空,不能够输出");
}
//输出节点的信息,注意将辅助变量temp后移,否则陷入死循环
do{
System.out.println(temp.next);
temp = temp.next;
}while(temp.next != null);
}
}
class HeroNode{
int HeroNO;
String HeroName;
String HeroNIckName;
HeroNode next;
//在这里不能够在构造方法里添加next,添加的next必须是初始化,但是最后一个变量的next是空的,每一个添加才给它赋值,所以不可以初始化
public HeroNode(int heroNO,String heroName,String heroNIckName){
this.HeroNO = heroNO;
this.HeroName = heroName;
this.HeroNIckName = heroNIckName;
}
@Override
public String toString() {
return "HeroNode{" +
"HeroNO=" + HeroNO +
", HeroName='" + HeroName + '\'' +
", HeroNIckName='" + HeroNIckName + '\'' + '}';
}
}
错误方式:
1、出现空指针
原因:即使找到了尾节点,他还是会把把temp指向尾节点的next,最后temp指的是空指针,没有next成员,所以不可以赋值
按照排名顺序进行添加
分析:
1.首先找到新添加节点的位置,设置辅助变量temp遍历所有元素,找到正确的位置
2.让新的节点和temp的next指向同一个变量
3.让temp的next指向新的节点
4.个人想法:
* 在原先的基础上 是否还要判定他是不是尾节点,没必要,我又不是从尾节点开始添加!
* 万一是空指针怎么办?先判定是不是空指针,在判定大小。
* 怎么判定大小?比前面大,比后面小。如果是最后一个怎么办?单纯的比前面大你就完了,回不去,他是单向表。
* 最后一个直接在后面进行添加
* 总体思路:从头开始找,找到比它小的,在判定他的下一个是否为空
* 换一个思路,从尾部开始找,不会出现空指针
* 遍历链表,找到最后一个元素,最后一个元素的序号和新插入的比较,比他大,就在后面直接添加。往前再找,任何一个比新插入的小的都是直接添加
* 确实不行,因为他是单向的,没办法实现从后往前,只能够从前往后。
5.结论:最后还是按照最初的想法,如果是按照顺序添加,还是双向链表比较好用。
代码实现
初始代码:
public void add(HeroNode heroNode){
HeroNode temp = head;
//遍历链表找到最后,头节点不能动,就创建辅助变量temp
//第一次添加,temp不会为空吗?
while (true){
if(temp.HeroNO < heroNode.HeroNO){
if(temp.next == null){
temp.next = heroNode;
break;
}else if(temp.next.HeroNO > heroNode.HeroNO){
heroNode.next = temp.next;
//*******如果写成temp.next = heroNode.next,temp后面的元素就全部丢失了,新插入的节点next域是空的,反过来,应该是把新插入的节点的next域变成原节点的next域
temp.next = heroNode;
break;
}
temp = temp.next;
}
}
运行结果
教程代码:
public void add(HeroNode heroNode){
//因为头节点不能动,只能通过一个辅助指针来帮助找到添加的位置
//因为单链表,我们找到的temp是位于添加位置前一个结点,否则插入不了,
HeroNode temp = head;
boolean flag = false;//flag表示添加的编号已经存在,默认是flase,不存在的
while (true){
if(temp.next == null){
break;
}
if(temp.next.HeroNO > heroNode.HeroNO){
break;
}else if(temp.next.HeroNO == heroNode.HeroNO){
flag = true;
break;
}
temp = temp.next;
}
if(flag ){
//不能再添加,英雄标号已经存在
System.out.println("不能再添加,英雄标号已经存在" + heroNode.HeroNO);
}else{
//插入到链表中,temp的后面
heroNode.next = temp.next;
temp.next = heroNode;
}
}
好处:
1.单向链表是不能从后往前,但是可以从temp的后一项的号码开始比较,比新插入项大,就是在该项前面,从后往前更快。
2.多了判定是否相同的步骤,更全面具体
3.先判定是否为最后一个指针,再进行比较