4.4双向链表
双向链表的增删改查:
代码实现:
package LinkedList;
public class DoubleLinkedListDemo {
public static void main(String[] args) {
HeroNode2 h1 = new HeroNode2(1, "h1", "nh1");
HeroNode2 h2 = new HeroNode2(2, "h2", "nh2");
HeroNode2 h4 = new HeroNode2(4, "h4", "nh4");
HeroNode2 h3 = new HeroNode2(3, "h3", "nh3");
HeroNode2 h5 = new HeroNode2(3, "h5", "nh5");
HeroNode2 h6 = new HeroNode2(8, "h8", "nh8");
HeroNode2 h7 = new HeroNode2(6, "h6", "nh6");
DoubleLinkedList hList = new DoubleLinkedList();
hList.addByOrder(h1);
hList.addByOrder(h2);
hList.addByOrder(h4);
hList.addByOrder(h3);
hList.addByOrder(h6);
hList.addByOrder(h6);
hList.list();
}
}
class HeroNode2 {
public int no;
public String name;
public String nickname;
public HeroNode2 next;
public HeroNode2 pre;
public HeroNode2(int hno, String hName, String hNickname) {
this.no = hno;
this.name = hName;
this.nickname = hNickname;
}
@Override
public String toString() {
return "HeroNode2{" +
"no=" + no +
", name='" + name + ''' +
", nickname='" + nickname + ''' +
'}';
}
}
class DoubleLinkedList {
public HeroNode2 headNode = new HeroNode2(0, "", "");
// 返回头节点
public HeroNode2 getHead() {
return headNode;
};
// 遍历双向链表
public void list() {
if (headNode.next == null) {
System.out.println("链表为空");
return;
}
HeroNode2 temp = headNode.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp);
temp = temp.next;
}
}
// 添加
public void add(HeroNode2 heroNode) {
HeroNode2 temp = headNode;
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
// 按顺序添加一个节点
public void addByOrder(HeroNode2 heroNode) {
// 定义一个辅助指针
HeroNode2 helper = headNode;
boolean flag = false;
while (true) {
if (helper.next == null) {
break;
}
if (helper.next.no > heroNode.no) {
break;
}
if (helper.next.no == heroNode.no) {
flag = true;
break;
}
helper = helper.next;
}
if (flag) {
System.out.printf("添加的元素%d已经存在", heroNode.no);
} else {
if (helper.next != null) {
heroNode.next = helper.next;
helper.next.pre = heroNode;
heroNode.pre = helper;
helper.next = heroNode;
}else{
helper.next = heroNode;
heroNode.pre = helper;
}
}
}
// 删除一个节点
public void del(int no) {
if(headNode.next == null) {
System.out.println("链表为空");
return;
}
// 定义一个辅助指针
HeroNode2 helper = headNode.next;
boolean flag = false;
while (true) {
if (helper == null) {
break;
}
if (helper.no == no) {
flag = true;
break;
}
helper = helper.next;
}
// 注意这里需要考虑,如果是删除最后一个节点,要防止出现空指针的情况
if (flag) {
helper.pre.next = helper.next;
if (helper.next != null) {
helper.next.pre = helper.pre;
}
} else {
System.out.printf("要删除的节点%d不存在 \n", no);
}
}
// 修改一个节点
public void update(HeroNode2 newHero) {
if(headNode.next == null){
System.out.println("链表为空");
return;
}
HeroNode2 temp = headNode.next;
boolean flag = false;
while (true) {
if (temp == null) {
break;
}
if (temp.no == newHero.no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.name = newHero.name;
temp.nickname = newHero.nickname;
} else {
System.out.printf("找不到编号为%d的英雄,无法更新", newHero.no);
}
}
}
4.5单项环形链表和约瑟夫问题
约瑟夫问题解决思路
用一个不带头结点的循环链表来解决约瑟夫问题:线构成一个有n个节点的单循环链表,然后从K节点起从1开始计数,记到m时,对应节点从链表中删除,然后再从被删除节点的下一个节点又从1开始计数,直到最后一个节点从链表中删除算法结束。
代码实现:
package LinkedList;
public class JosePhuDemo {
public static void main(String[] args) {
CircleSingleLinkedList circleList = new CircleSingleLinkedList();
circleList.addBoy(100);
circleList.showBoy();
circleList.countBoy(1, 7, 100);
}
}
class CircleSingleLinkedList {
private Boy first = null;
public void addBoy (int numbs) {
Boy helper = null;
if (numbs < 1) {
System.out.println("你输入的数没有意义,请重新输入");
return;
}
for (int i = 1; i <= numbs; i++) {
Boy newBoy = new Boy(i);
if (i == 1) {
first = newBoy;
first.setNext(first);
helper = first;
} else {
helper.setNext(newBoy);
newBoy.setNext(first);
helper = newBoy;
}
}
}
public void showBoy () {
if (first == null) {
System.out.println("没有任何小孩");
return;
}
Boy helper = first;
while (true) {
System.out.println(helper.getNo());
if(helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
}
public void countBoy (int startNum, int countNum, int num) {
if (startNum < 1 || countNum > num || startNum > num || first == null) {
System.out.println("输入条件不符合条件");
return;
}
Boy helper = first;
while (true) {
if (helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
for(int i=1; i < startNum; i++) {
first = first.getNext();
helper = helper.getNext();
}
while (true) {
if (helper == first) {
break;
}
for (int j=1; j < countNum; j++) {
first = first.getNext();
helper = helper.getNext();
}
System.out.printf("小孩%d出圈", first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.printf("此时留在圈内的小孩是%d", first.getNo());
}
}
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;
}
}
\