您的位置:首页 > 理论基础 > 数据结构算法

java的数据结构与算法(4)单项链表

2019-07-28 23:49 465 查看

什么是链表:
是以节点的方式存数据,有data域(存放数据),next域(存放下一个数据的指针)
最大的特征可以是不连续的
使用的场景:后端接受的数据是无序的,需要给前端返回一个有序的数据。

package cn.itjy.linkedlist;

public class SingleLinkedListDemo {
public static void main(String[] args) {
// test
// 先创建节点
HeroNode node1 = new HeroNode(1, "宋江", "及时雨");
HeroNode node2 = new HeroNode(2, "吴用", "智多星");
HeroNode node3 = new HeroNode(3, "李逵", "黑旋风");
HeroNode node4 = new HeroNode(4, "林冲", "豹子头");

SingleLinkedList linkedList = new SingleLinkedList();
/*
* linkedList.add(node1); linkedList.add(node4); linkedList.add(node2);
* linkedList.add(node3);
*/
linkedList.add2(node1);
linkedList.add2(node4);
linkedList.add2(node2);
linkedList.add2(node3);
linkedList.list();
HeroNode newHeroNode = new HeroNode(4, "小林", "豹头~~");
linkedList.update(newHeroNode);
// 显示
System.out.println("修改后的列表情况。。   ");
linkedList.list();
System.out.println("删除后的列表情况。。   ");
linkedList.delete(3);
linkedList.list();

// 测试
System.out.println("有效的节点个数=" + getLength(linkedList.getHead()));
}

// 查找单链表的倒数第K个节点【新浪面试题】
/*
* 思路:1.编写一个方法,接受head节点,同时接受index 2.index:表示倒数第index个节点 3.先把链表从头到尾遍历,得到链表的length
* 4.得到size后,我们从链表第一个开始遍历(size-index),就可以得到 5.如果找到,返回该节点,否则返回空
*/
public static HeroNode findLastIndexNode(HeroNode herd, int index) {
// 判断如果链表为空
if (herd.next == null) {
return null;
}
// 第一次遍历得到链表的长度(节点个数)
int size = getLength(herd);
// 第二次遍历 size-index 位置,就是倒数第k个节点
// 先做一个数据的校验
if (index <= 0|| index > size) {
return null;
}
//		定义一个辅助变量
return null;
}

// 方法:获取到单链表的节点的个数(如果带头节点的链表,需求不统计节点)
/**
* @param node
*            链表的头节点
* @return 有效节点的个数
*/
public static int getLength(HeroNode node) {
if (node.next == null) { //
return 0;
}
int length = 0;
// 定义一个辅助变量
HeroNode cur = node.next;
while (cur != null) {
length++;
cur = cur.next;
}
return length;
}
}

// 定义一个singleLinkedList管理我们的英雄
class SingleLinkedList {
// 先初始化一个头节点,头节点不要动,不存放具体的数据
private HeroNode head = new HeroNode(0, "", "");

// 返回头节点
public HeroNode getHead() {
return head;
}

// 添加节点到单向链表
/*
* 思路:当不考虑编号的顺序时 1.找到当前链表的最后节点 2.将最后这个节点的next 指向新的节点
*/
public void add(HeroNode heroNode) {
// 因为head节点不能动,因此我们需要一个辅助变量
HeroNode temp = head;
// 遍历链表
while (true) {
// 找到链表的最后
if (temp.next == null) { //
break;
}
// 如果没有找到最后,将temp后移
temp = temp.next;
}
// 当推出while循环时,temp就指向了链表的最后
// 最后的节点指向新的节点
temp.next = heroNode;
}

// 第二种方式在添加英雄时,根据排名将英雄插入到指定的位置
// (如果有这个排名,则添加失败,并给出提示)
public void add2(HeroNode heroNode) {
// 因为头节点不能动,因此通过辅助变量来帮助添加的位置
// 因为单链表,因此我们找的temp是位于添加位置的前一个节点,否则加入不了
HeroNode temp = head;
boolean flag = false; // 标识添加的编号是否存在,默认为false
while (true) {
if (temp.next == null) {// 说明temp已经在链表的最后
break;
}
if (temp.next.no > heroNode.no) { // 位置找到,就在temp后面插入
break;
} else if (temp.next.no == heroNode.no) { // 编号存在,希望添加的hero的编号已然存在
flag = true;
break;
}
temp = temp.next; // 后移 遍历列表
}
// 判断flag的值
if (flag) {
System.out.printf("插入英雄的编号%d已存在\n", heroNode.no);
} else {
// 插入到链表中,temp的后面
heroNode.next = temp.next;
temp.next = heroNode;
}
}

// 修改节点的信息,根据no编号来修改,即no编号不能改。
public void update(HeroNode newHeroNode) {
// 判断是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
// 找到需要修改的节点,根据no编号
// 定义一个辅助变量
HeroNode temp = head.next;
boolean flag = false; // 表示是否找到该节点
while (true) {
if (temp == null) {
break; // 到链表的最后
}
if (temp.no == newHeroNode.no) {
// 找到
flag = true;
break;
}
temp = temp.next;
}
// 根据flag 判断是否找到要修改的节点
if (flag) {
temp.name = newHeroNode.name;
temp.nickName = newHeroNode.nickName;
} else {
System.out.printf("没有找到编号%d节点,不能修改\n", newHeroNode.no);
}
}

// 删除节点
// 思路
/*
* 1.head 不能动,因此我们需要辅助节点确定位置 2.说明我们在比较时 , 是temp.next.no 和徐娅萍删除的no比较
*/
public void delete(int no) {
HeroNode temp = head;
// 找到是否找到待输出节点的前一个节点
boolean flag = false;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.no == no) {
// 找到待删除节点的前一个节点temp
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.next = temp.next.next;
} else {
System.out.printf("没有找到编号%d节点,不能删除\n", no);
}

}

// 显示链表
public void list() {
// 判断链表是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
// 因为头节点不能动,因此我们需要一个辅助变量
HeroNode temp = head.next;
while (true) {
// 链表最后
if (temp == null) {
break;
}
// 输出节点的信息
System.out.println(temp);
// 将temp后移,一定小心
temp = temp.next;
}

}

}

// 定义一个heroNode ,每一个HeroNode对象就是一个节点
class HeroNode {
public int no;
public String name;
public String nickName;
public HeroNode next; // 指向下一个节点
// 构造器

public HeroNode(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}

// 为了显示方便,我们重写toString
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickName=" + nickName + "]";
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: