1.单向链表的的定义
链表是有序的列表,这是它在内存中的存储,如下图所示:
- 链表是以节点的形式存储的,是链式存储
- 每个节点都包含两个部分,一个是 data 域,一个是 next 域指向下一个节点
- 每个节点不一定是连续存储
- 链表分为带头节点和不带头节点
2.单向链表的实现思路
(1)添加
添加节点的时候,直接添加到尾部。如下示意图:
- 先创建一个head节点,代表单向链表的头部
- 每添加一个节点就加入链表的后面
(2)按指定位置添加
添加节点的时候,按照排名插入到指定位置。如下示意图:
- 通过遍历找到添加指针的位置,需要temp临时指针标记
- 新节点.next = temp.next
- temp.next = 新节点
(3)修改
-
通过遍历找到节点
-
创建要修改的新节点对象
-
将新节点的属性复制给节点
-
删除节点
(4)删除
- 通过遍历找到需要删除节点的前一个节点,用temp标记
- temp.next = temp.next.next
- 被删除的节点会有java的垃圾回收机制处理
3.代码实现
package DataStructures.linkedlist;
import java.util.Stack;
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 singleLinkedList = new SingleLinkedList();
singleLinkedList.add(hero1);
singleLinkedList.add(hero4);
singleLinkedList.add(hero2);
singleLinkedList.add(hero3);
singleLinkedList.list();
reversePrint(singleLinkedList.getHead());
/*
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero3);
singleLinkedList.list();
HeroNode newHeroNode = new HeroNode(2, "", "~~");
singleLinkedList.update(newHeroNode);
singleLinkedList.list();
singleLinkedList.del(1);
singleLinkedList.del(4);
singleLinkedList.list();
System.out.println(getLength(singleLinkedList.getHead()));//2
HeroNode res = findLastIndexNode(singleLinkedList.getHead(), 3);
System.out.println("res=" + res);
*/
}
public static void reversePrint(HeroNode head) {
if(head.next == null) {
return;
}
Stack<HeroNode> stack = new Stack<HeroNode>();
HeroNode cur = head.next;
while(cur != null) {
stack.push(cur);
cur = cur.next;
}
while (stack.size() > 0) {
System.out.println(stack.pop());
}
}
public static void reversetList(HeroNode head) {
if(head.next == null || head.next.next == null) {
return ;
}
HeroNode cur = head.next;
HeroNode next = null;
HeroNode reverseHead = new HeroNode(0, "", "");
while(cur != null) {
next = cur.next;
cur.next = reverseHead.next;
reverseHead.next = cur;
cur = next;
}
head.next = reverseHead.next;
}
public static HeroNode findLastIndexNode(HeroNode head, int index) {
if(head.next == null) {
return null;
}
int size = getLength(head);
if(index <=0 || index > size) {
return null;
}
HeroNode cur = head.next;
for(int i =0; i< size - index; i++) {
cur = cur.next;
}
return cur;
}
public static int getLength(HeroNode head) {
if(head.next == null) {
return 0;
}
int length = 0;
HeroNode cur = head.next;
while(cur != null) {
length++;
cur = cur.next;
}
return length;
}
}
class SingleLinkedList {
private HeroNode head = new HeroNode(0, "", "");
public HeroNode getHead() {
return head;
}
public void add(HeroNode heroNode) {
HeroNode temp = head;
while(true) {
if(temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = heroNode;
}
public void addByOrder(HeroNode heroNode) {
HeroNode temp = head;
boolean flag = false;
while(true) {
if(temp.next == null) {
break;
}
if(temp.next.no > heroNode.no) {
break;
} else if (temp.next.no == heroNode.no) {
flag = true;
break;
}
temp = temp.next;
}
if(flag) {
System.out.print(heroNode.no);
} else {
heroNode.next = temp.next;
temp.next = heroNode;
}
}
public void update(HeroNode newHeroNode) {
if(head.next == null) {
System.out.println("链表为空");
return;
}
HeroNode temp = head.next;
boolean flag = false;
while(true) {
if (temp == null) {
break;
}
if(temp.no == newHeroNode.no) {
flag = true;
break;
}
temp = temp.next;
}
if(flag) {
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
} else {
System.out.printf("没有找到编号 %d 的节点\n", newHeroNode.no);
}
}
public void del(int no) {
HeroNode temp = head;
boolean flag = false;
while(true) {
if(temp.next == null) {
break;
}
if(temp.next.no == no) {
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.next;
}
}
}
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;
}
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}
4.总结
单向链表的实现还是比较简单的,最主要的是要弄清出每个节点怎么实现连接,删除节点如何操作。
标签:head,cur,temp,day4,HeroNode,next,链表,singleLinkedList,数据结构 From: https://blog.csdn.net/spechier/article/details/140394502