【数据结构与算法(java)】单链表 +倒数第N个节点+反转链表+逆序打印
链表
- 分为带头节点的链表和没有头结点的链表
单链表
//(带头结点)
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(hero2);
// singleLinkedList.add(hero3);
// singleLinkedList.add(hero4);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero3);
HeroNode hero5 = new HeroNode(4, "Lin", "豹子头");
singleLinkedList.update(hero5);
singleLinkedList.del(1);
singleLinkedList.list();
}
}
class SingleLinkedList {
private HeroNode head = new HeroNode(0, "", "");
public void add(HeroNode heroNode) {
HeroNode temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = heroNode;
}
public void list() {
if (head.next == null) {
return;
}
HeroNode temp = head.next;
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
public void addByOrder(HeroNode heroNode) {
HeroNode temp = head;
while (temp.next != null) {
if (temp.next.no > heroNode.no) {
break;
} else if (temp.next.no == heroNode.no) {
throw new RuntimeException("编号已存在");
}
temp = temp.next;
}
heroNode.next = temp.next;
temp.next = heroNode;
}
public void update(HeroNode newHeroNode) {
if (head.next == null) {
return;
}
HeroNode temp = head.next;
boolean flag = false;
while (temp != null) {
if (temp.no == newHeroNode.no) {
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
flag = true;
break;
}
temp = temp.next;
}
if (!flag) {
throw new RuntimeException("找不到该编号的节点");
}
}
public void del(int no) {
HeroNode temp = head;
boolean flag =false;
while (temp.next!=null) {
if (temp.next.no==no) {
flag=true;
temp.next=temp.next.next;
}
temp=temp.next;
}
if (!flag) {
System.out.println("不存在该节点");
}
}
}
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 + "]";
}
}
-
倒数第N个节点
public static HeroNode findLastIndexNode(HeroNode head, int index) { if (head.next == null) { return null; } int length = getLength(head); if (index <= 0 || index > length) { return null; } HeroNode temp = head.next; int currentIndex = 0; while (temp != null) { currentIndex++; if (currentIndex == length + 1 - index) { return temp; } temp = temp.next; } return null; }
-
反转链表
思路:
- 先定义一个节点 reverseHead = new HeroNode();
- 从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表 reverseHead 的最前端.
- 原来的链表的 head.next = reverseHead.next
public static void reverseList(HeroNode head) {
if (head.next == null || head.next.next == null) {
return;
}
HeroNode newHead = new HeroNode(0, "", "");
HeroNode cur = head.next;
HeroNode next;
while (cur != null) {
next = cur.next;
cur.next = newHead.next;
newHead.next = cur;
cur = next;
}
head.next = newHead.next;
}
-
逆序打印链表
思路:
-
法一:先反转,再遍历(但是会破坏原有结构)
-
法二:可以利用栈(建议)
public static void reversePrint(HeroNode head) { if (head.next==null) { return; } Stack<HeroNode> stack = new Stack<>(); HeroNode temp = head.next; while (temp!=null) { stack.push(temp); temp=temp.next; } while(!stack.empty()) { System.out.println(stack.pop()); } }
-