链表
单链表
定义节点
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 +
'}';
}
}
建立单链表
class SingleLinkedList {
//头节点
private HeroNode head = new HeroNode(0, "", "");
public HeroNode getHead() {
return head;
}
public void setHead(HeroNode head) {
this.head = head.next;
}
//添加节点
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.println("编号已存在 不能插入");
} 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.println("没找到 不能修改");
}
}
//打印链表
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;
}
}
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.println("要删除的节点不存在");
}
}
}
测试代码 建立单链表(按照节点输入顺序)
public class SingleLinkedListDemo {
public static void main(String[] args) {
HeroNode hero1 = new HeroNode(1, "aaa", "aaa1");
HeroNode hero2 = new HeroNode(3, "bbb", "bbb1");
HeroNode hero3 = new HeroNode(5, "ccc", "ccc1");
HeroNode hero4 = new HeroNode(7, "ddd", "ddd1");
}
SingleLinkedList singleLinkedList1 = new SingleLinkedList();
singleLinkedList1.add(hero1);
singleLinkedList1.add(hero2);
singleLinkedList1.add(hero3);
singleLinkedList1.add(hero4);
singleLinkedList1.list();
}
测试代码 建立单链表(按照节点编号顺序)
HeroNode hero1 = new HeroNode(1, "aaa", "aaa1");
HeroNode hero2 = new HeroNode(7, "bbb", "bbb1");
HeroNode hero3 = new HeroNode(5, "ccc", "ccc1");
HeroNode hero4 = new HeroNode(3, "ddd", "ddd1");
SingleLinkedList singleLinkedList1 = new SingleLinkedList();
singleLinkedList1.addByOrder(hero1);
singleLinkedList1.addByOrder(hero2);
singleLinkedList1.addByOrder(hero3);
singleLinkedList1.addByOrder(hero4);
singleLinkedList1.list();
删除节点
System.out.println("删除3号节点:");
singleLinkedList1.del(3);
singleLinkedList1.list();
修改节点
System.out.println("修改5号节点");
HeroNode newHeroNode = new HeroNode(5, "eee", "eee1");
singleLinkedList1.update(newHeroNode);
singleLinkedList1.list();
获取链表长度
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;
}
测试代码:
System.out.println("链表长度为: " + getLength(singleLinkedList1.getHead()));
查找倒数第K个节点
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;
}
测试代码:
System.out.println("查看倒数第1个节点");
HeroNode res = findLastIndexNode(singleLinkedList1.getHead(), 1);
System.out.println(res);
单链表逆置
利用栈实现链表逆置
public static void reversePrint(HeroNode head) {
if (head.next == null) {
return;
}
Stack<HeroNode> stack = new Stack<~>();
HeroNode cur = head.next;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
while (stack.size() > 0) {
System.out.println(stack.pop());
}
}
测试代码:
singleLinkedList1.list();
System.out.println("逆置后:");
reversePrint(singleLinkedList1.getHead());
头插法实现链表逆置
public static void reverseList(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;
}
测试代码:
System.out.println("逆置后:");
reverseList(singleLinkedList1.getHead());
singleLinkedList1.list();
单链表合并(两个有序单链表 合并之后依然有序)
public static HeroNode SingleLinkedListMerge(HeroNode list1, HeroNode list2) {
HeroNode temp = new HeroNode(0, "", "");
HeroNode head = temp;
while (list1 != null && list2 != null) {
if (list1.no < list2.no) {
temp.next = list1;
list1 = list1.next;
} else {
temp.next = list2;
list2 = list2.next;
}
temp = temp.next;
}
if (list1 == null) {
temp.next = list2;
}
if (list2 == null) {
temp.next = list1;
}
return head.next;
}
测试代码:
HeroNode hero1 = new HeroNode(1, "aaa", "aaa1");
HeroNode hero2 = new HeroNode(3, "bbb", "bbb1");
HeroNode hero3 = new HeroNode(5, "ccc", "ccc1");
HeroNode hero4 = new HeroNode(7, "ddd", "ddd1");
HeroNode hero5 = new HeroNode(2, "aaa", "aaa2");
HeroNode hero6 = new HeroNode(4, "bbb", "bbb2");
HeroNode hero7 = new HeroNode(6, "ccc", "ccc2");
HeroNode hero8 = new HeroNode(8, "ddd", "ddd2");
SingleLinkedList singleLinkedList1 = new SingleLinkedList();
singleLinkedList1.add(hero1);
singleLinkedList1.add(hero2);
singleLinkedList1.add(hero3);
singleLinkedList1.add(hero4);
System.out.println("单链表:");
singleLinkedList1.list();
SingleLinkedList singleLinkedList2 = new SingleLinkedList();
singleLinkedList2.add(hero5);
singleLinkedList2.add(hero6);
singleLinkedList2.add(hero7);
singleLinkedList2.add(hero8);
System.out.println("单链表:");
singleLinkedList2.list();
System.out.println("合并后:");
SingleLinkedList singleLinkedList3 = new SingleLinkedList();
HeroNode newHead = SingleLinkedListMerge(singleLinkedList1.getHead(), singleLinkedList2.getHead());
singleLinkedList3.setHead(newHead);
singleLinkedList3.list();
双链表
定义节点
class HeroNode2 {
public int no;
public String name;
public String nickname;
public HeroNode2 next;
public HeroNode2 pre;
public HeroNode2(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "HeroNode2{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
建立双向链表
class DoubleLinkedList {
private HeroNode2 head = new HeroNode2(0, "", "");
public HeroNode2 getHead() {
return head;
}
public void list() {
if (head.next == null) {
System.out.println("链表为空");
return;
}
HeroNode2 temp = head.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp);
temp = temp.next;
}
}
public void addByOrder(HeroNode2 heroNode) {
HeroNode2 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.println("编号已存在 不能插入");
} else {
if (temp.next == null) {
temp.next = heroNode;
heroNode.pre = temp;
} else {
heroNode,next = temp.next;
temp.next.pre = heroNode;
heroNode.pre = temp;
temp.next = heroNode;
}
}
}
//添加一个节点到双向链表的最后
public void add(HeroNode2 heroNode) {
HeroNode2 temp = head;
while(true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
public void update(HeroNode2 newHeroNode) {
if (head.next == null) {
System.out.println("链表为空");
return;
}
HeroNode2 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.println("没找到");
}
}
public void del(int no) {
if (head.next == null) {
System.out.println("链表为空");
return;
}
HeroNode2 temp = head.next;
boolean flag = false;
while (true) {
if (temp == null) {
break;
}
if (temp.no == no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
} else {
System.out.println("要删除的节点不存在");
}
}
}
测试
建立双向链表(按节点加入顺序)
public class DoubleLinkedListDemo {
public static void main(String[] args) {
HeroNode2 hero1 = new HeroNode2(1, "a", "a1");
HeroNode2 hero2 = new HeroNode2(4, "b", "b1");
HeroNode2 hero3 = new HeroNode2(3, "c", "c1");
HeroNode2 hero4 = new HeroNode2(5, "e", "e1");
HeroNode2 hero5 = new HeroNode2(2, "d", "d1");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.add(hero1);
doubleLinkedList.add(hero2);
doubleLinkedList.add(hero3);
doubleLinkedList.add(hero4);
doubleLinkedList.add(hero5);
doubleLinkedList.list();
}
}
建立双向链表(按节点编号顺序)
HeroNode2 hero1 = new HeroNode2(1, "a", "a1");
HeroNode2 hero2 = new HeroNode2(4, "b", "b1");
HeroNode2 hero3 = new HeroNode2(3, "c", "c1");
HeroNode2 hero4 = new HeroNode2(5, "e", "e1");
HeroNode2 hero5 = new HeroNode2(2, "d", "d1");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.addByOrder(hero1);
doubleLinkedList.addByOrder(hero2);
doubleLinkedList.addByOrder(hero3);
doubleLinkedList.addByOrder(hero4);
doubleLinkedList.addByOrder(hero5);
doubleLinkedList.list();
修改节点
HeroNode2 newHeroNode = new HeroNode2(4, "e", "e1");
doubleLinkedList.update(newHeroNode);
System.out.println("修改后");
doubleLinkedList.list();
删除节点
doubleLinkedList.del(3);
System.out.println("删除后:");
doubleLinkedList.list();
约瑟夫问题(循环链表)
场景
代码实现
定义节点
class Boy {
private int no;
private Boy next;
public Boy(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
循环链表
class CircleSingleLinkedList {
private Boy first = null;
public void addBoy(int nums) {
if (nums < 1) {
System.out.println("nums的值不正确");
return;
}
Boy curBoy = null;
for (int i = 1; i <= nums; i++) {
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
first.setNext(first);
curBoy = first;
} else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}
public void showBoy() {
if (first == null) {
System.out.println("没有任何小孩");
return;
}
Boy curBoy = first;
while (true) {
System.out.printf("小孩的编号 %d\n", curBoy.getNo());
if (curBoy.getNext() == first) {
break;
}
curBoy = curBoy.getNext();
}
}
public void countBoy(int startNo, int countNum, int nums) {
if (first == null || startNo < 1 || startNo > nums) {
System.out.println("参数有误");
return;
}
Boy helper = first;
while (true) {
if (helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
for (int j = 0; j < startNo - 1; j++) {
first = first.getNext();
helper = helper.getNext();
}
while (true) {
if (helper == first) {
break;
}
for (int j = 0; j < countNum - 1; j++) {
first = first.getNext();
helper = helper.getNext();
}
System.out.printf("小孩%d出圈\n", first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.printf("最后留在圈中的小孩编号%d\n", first.getNo());
}
}
测试
public class Josefu {
public static void main(String[] args) {
CircleSingLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(5);
circleSingleLinkedList.showBoy();
circleSingleLinkedList.countBoy(1, 2, 5);
}
}