链表是有序列表
小结:
1:链表是以节点的方式来储存,是链式结构
2:每个节点包含data域,next域:指向下一个节点
3:链表的各个节点不一定是连续存放
4:链表分为带头结点的链表和没有头结点的链表,根据实际的需求来确定
链表的独特
链表主要是便于管理长度或数量不确定的数据,相对于数组,链表处理这种数据时比较节省内存。动态语言通常不大需要链表,因为动态语言的解释器帮你管理内存,但当你对空间效率或插入动作的效率有特殊要求时也可在动态语言中使用链表。
链表介绍:
链表在内存中存储如下:
单项列表实现:
代码实现:
package com.linkedlist;
public class demo01 {
public static void main(String[] args) {
//测试
//先创建节点
HeroNode hero1 = new HeroNode(1, "盖伦", "德玛西亚之力");
HeroNode hero2 = new HeroNode(2, "嘉文四世", "德玛西亚皇子");
HeroNode hero3 = new HeroNode(3, "赵信", "德邦总管");
//创建链表
SingleLinkedList sing = new SingleLinkedList();
//加入链表
sing.add(hero1);
sing.add(hero2);
sing.add(hero3);
//显示链表
sing.list();
}
}
/*定义SingleLinkedList 来管理我们的角色*/
class SingleLinkedList {
// 先定义一个头及节点,头结点不动不存放具体的数据
private HeroNode head = new HeroNode(0, "", "");
// 添加节点到单项链表
// 思路:当不考虑编号顺序时
// 1:找到当前链表的最后节点
// 2:将最后节点的next指向新加入的节点
public void add(HeroNode heroNode) {
// 因为head头结点不能动,因此我们需要一个辅助遍历temp;
HeroNode temp = head;
// 遍历链表找到最后
while (true) {
// 找到链表的最后
if (temp.next == null) {
break;
}
// 如果没有找到就将temp的值往后移
temp = temp.next;
}
// 当退出while循环时,temp就指向了最后的链表
// 将最后这个节点的next指向新加入的节点
temp.next = heroNode;
}
// 显示链表【遍历】
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;//指向下一个节点
// 重写tostring
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
//构造器
public HeroNode(int hno, String hname, String hNickname) {
this.name = hname;
this.no = hno;
this.nickname = hNickname;
}
}
效果展示:
链表面试题
1.查找出链表中一共有多少个节点
实现思路:遍历全部节点通过length累计,当判断节点的next为空时跳出,再返回length。
/**
* 创建获取到单链表的节点的个数(头结点不算)
*/
public static int getLength(HeroNode head){
if(head.next==null){
System.out.println("链表为空");
return 0;
}
int lenght = 0;
//定义一个辅助变量
HeroNode cur = head;
while(cur.next!=null){
lenght++;
cur=cur.next;
}
return lenght;
}
}
效果展示:
HeroNode{no=2, name='嘉文四世', nickname='德玛西亚皇子'}
HeroNode{no=3, name='德莱厄斯', nickname='诺克萨斯之手'}
HeroNode{no=4, name='艾希', nickname='寒冰射手'}
HeroNode{no=5, name='希瓦娜', nickname='龙女'}
这个链表有4
2.查找链表中的倒数第n个节点
/**
* 创建查找链表倒数第n个节点的方法
* 思路:
* 1.编写一个方法接收head节点,同时接收一个index(要寻找的节点位置)
* 2.index表示倒数第几个的节点
* 3.先把链表从头遍历到尾,的得到链表的长度(可以用已经写好的方法getLength())
* 4.得到size后我们从链表的第一个遍历到(size-index)个
* 5.如果找到就返回找到的节点,没有找到就返回null
*/
public static HeroNode findLastIndexNode(HeroNode head,int index){
//判断传入的head是不是为空,为空就返回null
if(head.next==null){
System.out.println("链表为空");
return null;//没有找到
}
//获取到链表长度
int size = getLength(head);
//判断传入的index是否是有效值
if (size<index||index<=0){
System.out.println("请传入正确的值");
return null;
}
//定义一个辅助节点
HeroNode cur = head.next;
//定义一个for循环size-index次得到需要找到的节点
for(int i =0;i<size-index;i++){
cur=cur.next;
}
//返回找到的节点
return cur;
}
}
效果展示:
//链表的倒数第几个节点
HeroNode a = SingleLinkedList.findLastIndexNode(sing.getHead(),2);
System.out.println(a.name);
HeroNode{no=1, name='盖伦', nickname='德玛西亚之力'}
HeroNode{no=2, name='嘉文四世', nickname='德玛西亚皇子'}
HeroNode{no=3, name='德莱厄斯', nickname='诺克萨斯之手'}
HeroNode{no=4, name='艾希', nickname='寒冰射手'}
HeroNode{no=5, name='赵信', nickname='德邦总管'}
这个链表有5
艾希