在学习数据结构中链表的时候,总是会看到一个经典的图
其中头指针中存储着下一个结点的位置信息,而通过地址找到头指针的下一个指针时,又会从其指针域找到下一个地址,这在逻辑上来说十分正确.
但是今天敲代码,我突然思路卡住了,前几天一直在看数组的问题,于是链表的一个问题难住我了--------链表是如何完成指向下一个地址的,我第一个想到了数组中的指针,但是发现这样自定义指针的方法又变成了对数组的处理 而不是对单链表进行处理.
首先设置单链表元素类,包含单链表元素中存储的信息 如编号 名字等 尤其注意设置该类的变量
在java中,非基本数据类型的初始化都需要在堆中开辟内存空间,而变量实际是指向堆中的地址,当这个变量被引用时,如head.next就会找到这个地址,再对这个地址进行赋值等操作,这也是在单链表元素类声明一个同样类的变量的原因.
设置好单链表元素类后开始设置单链表类
先设置一个头节点,这个节点不存放信息,但是要存放下一个节点的位置
下面设置增加元素和查看元素的方法
注意先判断链表是否为空,然后再对链表进行遍历.下面给出代码
package com.data.linkedlist;
import org.junit.Test;
public class LinkedListDemo {
@Test
public void test() {
HeroNode heroNode = new HeroNode(1, "艾伦", "进击");
SingleLinkedList singleLinkedList = new SingleLinkedList();
singleLinkedList.addHero(heroNode);
singleLinkedList.addHero(new HeroNode(2, "阿明", "超大"));
singleLinkedList.showHero();
}
}
class SingleLinkedList {
//初始化头节点,头节点不要动
HeroNode head = new HeroNode(0, "", "");
HeroNode temp = head.next;
void addHero(HeroNode heroNode) {
HeroNode temp = head;
while (true) {//遍历链表
if (temp.next == null) {//找到链表的最后一个位置
break;
}
temp = temp.next;//往后寻找
}
temp.next = heroNode;
}
void showHero() {
HeroNode temp = head.next;
if (temp == null) {
System.out.println("链表为空");
return;
}
while (true) {
if (temp == null) {
break;
}
System.out.println(temp.toString());
temp = temp.next;
}
}
}
//初始化链表中元素
class HeroNode {
public int heroNo;
public String heroName;
public String nickName;
public HeroNode next;//指向下一个节点
public HeroNode(int heroNo, String heroName, String nickName) {
this.heroName = heroName;
this.heroNo = heroNo;
this.nickName = nickName;
}
@Override
public String toString() {
return "HeroNode{" +
"heroNo=" + heroNo +
", heroName='" + heroName + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}
下一步实现根据序号进行排序 反转等操作,目前只是基础的添加和查看
-------------------添加根据序号放入方法-----------------------------
void addByOrder(HeroNode heroNode) {
HeroNode temp = head;
boolean flag = false;
while (true) {
if (temp.next == null) {//代表已经遍历到了最后一个
break;
}
if (heroNode.heroNo <temp.next.heroNo) {//位置找到,在temp的后面插入
break;
}
if (heroNode.heroNo == temp.heroNo) {
flag = true;
break;
}
temp = temp.next;//指针后移
}
if (flag) {
System.out.println("序号冲突,无法添加.");
} else {
heroNode.next = temp.next;
temp.next = heroNode;
}
}
public void test() {
HeroNode heroNode = new HeroNode(1, "艾伦", "进击");
HeroNode heroNode1 = new HeroNode(3, "芜湖", "起飞");
HeroNode heroNode2 = new HeroNode(5, "uzi", "小狗");
HeroNode heroNode3 = new HeroNode(2, "jack", "水");
HeroNode heroNode4 = new HeroNode(4, "迪迦", "光");
SingleLinkedList singleLinkedList = new SingleLinkedList();
singleLinkedList.addByOrder(heroNode);
singleLinkedList.addByOrder(heroNode1);
singleLinkedList.addByOrder(heroNode2);
singleLinkedList.addByOrder(heroNode3);
singleLinkedList.addByOrder(heroNode4);
// singleLinkedList.addHero(heroNode);
// singleLinkedList.addHero(new HeroNode(2, "阿明", "超大"));
singleLinkedList.showHero();
}
可以看到,已经实现了按序号插入功能.
-------------------------------实现了按序号删除功能----------------------------
//删除链表中的节点信息
void deleteHero(int heroNo){
HeroNode temp = head;
while (true){
if (temp.next==null){
System.out.println("未找到");
break;
}
if (temp.next.heroNo==heroNo){
temp.next = temp.next.next;
break;
}
temp = temp.next;
}
}
-------------------------------------------------------根据编号修改节点信息
void changeHero(int heroNo,String heroName,String nickName ){
HeroNode temp = head;
while (true){
if (temp.next==null){
System.out.println("未找到");
break;//跳出遍历
}
if (temp.next.heroNo==heroNo){//根据标号确定要更改的信息
temp.next.heroName = heroName;
temp.next.nickName = nickName;
break;
}
temp = temp.next;
}
}
单链表的基本操作到这里也就结束了.