java之单链表
文章内容选自尚硅谷数据结构和算法,jdk8,eclipse环境
按照插入顺序的单链表
package linkedlist;
public class SingleLinkedListDemo {
public static void main(String[] args) {
HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟");
HeroNode hero3 = new HeroNode(3,"吴用","智多星");
HeroNode hero4 = new HeroNode(4,"林冲","豹子头");
SingleLinkedList test = new SingleLinkedList();
test.addNode(hero1);
test.addNode(hero2);
test.addNode(hero4);
test.addNode(hero3);
test.showList();
}
}
class HeroNode{
int no ;
String name;
String nickname;
HeroNode next;
public HeroNode(int no,String name,String nickname){
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}
class SingleLinkedList{
HeroNode head = new HeroNode(0,"","");
public void addNode(HeroNode node){
HeroNode tmp = head;
while(true){
if(tmp.next == null)
{
tmp.next = node;
break;
}
tmp = tmp.next;
}
}
public void showList(){
HeroNode tmp;
if(head.next == null)
{
System.out.println("列表是空的");
return;
}
tmp = head;
tmp = tmp.next;
while(true){
if(tmp.next == null)
{
System.out.println(tmp);
break;
}
System.out.println(tmp);
tmp = tmp.next;
}
}
}
运行结果为
HeroNode [no=1, name=宋江, nickname=及时雨]
HeroNode [no=2, name=卢俊义, nickname=玉麒麟]
HeroNode [no=4, name=林冲, nickname=豹子头]
HeroNode [no=3, name=吴用, nickname=智多星]
链表的输出完全按照链表的添加顺序,没办法根据编号顺序插入和输出。
分析代码:
首先创建一个英雄节点HeroNode类,必须要有构造器和重写的toString(),方便输出。toString()是eclipse重写的方法,不能包含next这个属性,否则会输出从起始节点到尾节点的所有对象。
然后创建一个SingleLinkedList类,把HeroNode类的引用数据类型的变量作为SingleLinkedList类方法的形参,再在main方法中调用SingleLinkedList类的方法。
按照标号顺序插入的单链表
按照标号顺序插入的单链表就是链表的逻辑顺序是按照对象的编号循序排列的。在是上一个的基础上,新增了addNodeByOrder,modifyNode,delNode三个方法
package linkedlist;
public class SingleLinkedListDemo {
public static void main(String[] args) {
HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟");
HeroNode hero3 = new HeroNode(3,"吴用","智多星");
HeroNode hero4 = new HeroNode(4,"林冲","豹子头");
SingleLinkedList test = new SingleLinkedList();
// test.addNode(hero1);
// test.addNode(hero2);
// test.addNode(hero4);
// test.addNode(hero3);
test.addNodeByOrder(hero3);
test.addNodeByOrder(hero2);
test.addNodeByOrder(hero1);
test.addNodeByOrder(hero4);
HeroNode newHero = new HeroNode(2,"小卢","小玉");
test.modifyNode(newHero);
test.showList();
test.delNode(2);
test.showList();
test.delNode(4);
test.showList();
}
}
class HeroNode{
int no ;
String name;
String nickname;
HeroNode next;
public HeroNode(int no,String name,String nickname){
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}
class SingleLinkedList{
HeroNode head = new HeroNode(0,"","");
public void addNode(HeroNode node){
HeroNode tmp = head;
while(true){
if(tmp.next == null)
{
tmp.next = node;
break;
}
tmp = tmp.next;
}
}
public void addNodeByOrder(HeroNode node){
HeroNode tmp = head;
boolean flag = false;
while(true){
if(tmp.next == null){
break;
}else if(tmp.next.no > node.no){
break;
}else if(tmp.next.no == node.no )
{
flag = true;
break;
}
tmp = tmp.next;
}
if(flag == true)
{
System.out.printf("输入的编号%d已存在",node.no);
System.out.println();
}
else{
node.next = tmp.next; //是tmp.next给node.next,不要记成了tmp.next.next,null是没有.next 属性的
tmp.next = node;
}
}
public void modifyNode(HeroNode node){
HeroNode tmp = head;
if(tmp.next == null)
{
System.out.println("列表为空");
return;
}
while(true){
if(tmp.next == null){
System.out.println("没有找到要修改的节点");
break;
}
if(tmp.next.no == node.no){
tmp.next.name = node.name;
tmp.next.nickname = node.nickname;
System.out.println("已找到要修改的节点,修改节点成功");
break;
}
tmp = tmp.next;
}
}
public void delNode(int no){
HeroNode tmp = head;
if(tmp.next == null)
{
System.out.println("链表为空");
return;
}
while(true){
if(tmp.next == null){
System.out.println("没有找到要删除的节点");
break;
}
if(tmp.next.no == no){
tmp.next = tmp.next.next;
System.out.println("删除节点成功");
break;
}
tmp = tmp.next;
}
}
public void showList(){
HeroNode tmp;
if(head.next == null)
{
System.out.println("列表是空的");
return;
}
tmp = head;
tmp = tmp.next;
while(true){
if(tmp.next == null)
{
System.out.println(tmp);
break;
}
System.out.println(tmp);
tmp = tmp.next;
}
}
}
对于这三个方法,tmp都指向的是要操作对象的前一个元素,通过tmp.next来进行对目标对象的操作。
其中,addNodeByOrder()按照编号顺序添加的方法的核心是
node.next = tmp.next; //是tmp.next给node.next,不要记成了tmp.next.next,null是没有.next 属性的
tmp.next = node;
假如在A,B中插入C,先把B的地址给C的next域,让C指向B,在把C的地址给A的next域,让A指向C,即完成了A->C->B的插入操作。
delNode()方法的核心代码为
tmp.next = tmp.next.next;
假如要删除A,B,C中的B,就直接把C的地址给A的next域,让A直接指向C,B没有指针指向它了,会被JVM当做垃圾回收掉。
modifyNode(HeroNode node)即修改一个节点的属性,必须事先创建好一个新节点,把新节点的属性赋值给老节点,但是注意,因为链表是按照编号顺序添加的,所有修改节点方法不能修改节点编号。
if(tmp.next.no == node.no){
tmp.next.name = node.name;
tmp.next.nickname = node.nickname;
System.out.println("已找到要修改的节点,修改节点成功");
break;
}
运行结果为
已找到要修改的节点,修改节点成功
HeroNode [no=1, name=宋江, nickname=及时雨]
HeroNode [no=2, name=小卢, nickname=小玉]
HeroNode [no=3, name=吴用, nickname=智多星]
HeroNode [no=4, name=林冲, nickname=豹子头]
删除节点成功
HeroNode [no=1, name=宋江, nickname=及时雨]
HeroNode [no=3, name=吴用, nickname=智多星]
HeroNode [no=4, name=林冲, nickname=豹子头]
删除节点成功
HeroNode [no=1, name=宋江, nickname=及时雨]
HeroNode [no=3, name=吴用, nickname=智多星]