链表
单链表
-
不考虑排名,直接往最后一个位置插入元素
package com.zhangan.linkedlist; 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.list(); } } //定义一个SingleLinkedList 管理 class SingleLinkedList { //初始化一个头节点 private HeroNode head = new HeroNode(0, "", ""); //添加节点到单向链表 //1。找到当前链表的最后节点 //2。将最后这个节点的next指向新的节点 public void add(HeroNode heroNode) { //头节点不能动 需要一个辅助变量来遍历链表 HeroNode temp = head; //遍历链表,找到最后 while (true) { //找到了最后一个节点 if (temp.next == null) { break; } //如果不是最后一个节点 temp后移 temp = temp.next; } //循环结束,temp指向链表最后 temp.next = heroNode; } //展示链表 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.toString()); temp = temp.next; } } } //定义一个节点 class HeroNode { public int no; public String name; public String nickname; public HeroNode next; //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 + '}'; } }
-
根据排名添加
//根据英雄的排名 添加到指定位置 public void addByOrder(HeroNode heroNode) { //辅助变量来找合适的添加的位置 HeroNode temp = head; boolean flag = false;//添加的编号是否存在 while (true) { if (temp.next == null) {//说明temp在链表最后 break; } if (temp.next.no > heroNode.no) {//位置找到了 就在temp之后 break; } else if (temp.next.no == heroNode.no) { flag = true;//编号已存在 break; } temp = temp.next;//后移 } if (flag) { System.out.println("准备插入的英雄编号已经存在了"); } else { //插入链表 temp的后面 heroNode.next = temp.next; temp.next = heroNode; } }
-
根据编号修改
//修改节点的信息 根据编号no来修改 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 delete(Integer id) { //判断链表是否为空 if (head.next == null) { System.out.println("空链表,无值"); return; } HeroNode temp = head; boolean flag = false;//是否找到要删除的节点 while (true) { if (temp.next == null) { break; } if (temp.next.no == id) { flag = true; break; } temp = temp.next; } if (flag) { temp.next = temp.next.next; } else { System.out.println("没有该英雄"); } }
双向链表
代码实现:
package com.zhangan.linkedlist;
//创建双向链表的节点
class Node {
public int no;
public String name;
public String nickname;
public Node next;//指向下一个节点
public Node pre;//指向前一个结点
public Node(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
class DoubleLinkedList {
//初始化 头节点
private Node head = new Node(0, "", "");
public Node getHead() {
return head;
}
//判断链表是否为空
public boolean isEmpty() {
return head.next == null;
}
//遍历链表
public void list() {
if (isEmpty()) {
System.out.println("链表为空");
return;
}
Node temp = head.next;
while (temp != null) {
System.out.println(temp.toString());
temp = temp.next;
}
}
//添加节点
public void add(Node node) {
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
node.pre = temp;
}
//修改节点
public void update(Node node) {
if (isEmpty()) {
System.out.println("链表为空");
return;
}
Node temp = head.next;
boolean flag = false;
while (temp != null) {
if (temp.no == node.no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.name = node.name;
temp.nickname = node.nickname;
} else {
System.out.println("没有该数据");
}
}
//删除节点
public void delete(Integer id) {
if (isEmpty()) {
System.out.println("链表为空");
return;
}
Node temp = head.next;
boolean flag = false;//是否找到要删除的节点
while (temp != null) {
if (temp.no == id) {
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 void addByOrder(Node node) {
Node temp = head;
boolean flag = false;//添加的编号是否存在
while (temp.next != null) {
if (temp.next.no > node.no) {
break;
}
if (temp.next.no == node.no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("该编号存在:" + node.no);
} else {
node.next = temp.next;
temp.next = node;
node.pre = temp;
}
}
}
public class DoubleLinkedListDemo {
public static void main(String[] args) {
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
Node node1 = new Node(1, "name1", "111");
Node node2 = new Node(2, "name2", "222");
Node node3 = new Node(3, "name3", "333");
Node node4 = new Node(4, "name4", "444");
Node node5 = new Node(5, "name5", "555");
doubleLinkedList.addByOrder(node5);
doubleLinkedList.addByOrder(node4);
doubleLinkedList.addByOrder(node3);
doubleLinkedList.addByOrder(node2);
doubleLinkedList.addByOrder(node1);
doubleLinkedList.list();
System.out.println("---------------------------");
//测试修改
// Node node5update = new Node(5, "name5修改", "555修改");
// doubleLinkedList.update(node5update);
// doubleLinkedList.list();
//测试删除
// doubleLinkedList.delete(2);
// doubleLinkedList.list();
}
}
单向环形链表
构建一个单向的环形链表思路
1.先创建第一个节点,让first指向该节点,并形成环形
2.后面当我们每创建一个新的节点,就把该节点,加入到已有的环形链表中即可.
遍历环形链表
1.先让一个铺助指针(变量) curBoy,指向first节点
2然后通过一个while循环遍历该环形链表即可curBoy.next == first结束
出圈思路:
1.需求创建一个辅助指针 helper ,事先应该指向环形链表的最后这个节点.
2.当小孩报数时,i让first和helper指针同时的移动m -1次
3.这时就可以将first指向的小孩节点出圈
first = first. Next
helper.next =first
原来first指向的节点就没有任何引用,就会被回收
代码部分:
package com.zhangan.linkedlist;
//创建一个boy 表示一个节点
class Boy {
private int no;
private Boy next;
public Boy(int no) {
this.no = no;
}
@Override
public String toString() {
return "Boy{" +
"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 {
//创建一个first 节点
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; //curBoy指向第一个小孩
} else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}
//遍历当前环形链表
public void list() {
if (first == null) {
System.out.println("链表为空");
return;
}
Boy curBoy = first;
while (true) {
System.out.println("小孩的编号:" + curBoy.getNo());
if (curBoy.getNext() == first) {//已经遍历完成
break;
}
curBoy = curBoy.getNext();
}
}
//根据用户输入 计算小孩出圈的顺序
/**
* @param startNo 第几个小孩开始数数
* @param countNum 数几下
* @param nums 共有多少小孩
*/
public void outBoy(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) {//说明helper指向最后一个小孩节点
break;
}
helper = helper.getNext();
}
//第几个小孩报数 first移动到该小孩 helper紧随其后
for (int i = 0; i < startNo - 1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//当小孩报数时,让first和helper指针同时的移动countNum-1次,然后出圈
while (true) {
if (helper == first) {//圈里只有一个人了
break;
}
for (int i = 0; i < countNum - 1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//此时first指向的节点就是要出圈的小孩
System.out.println("小孩" + first.getNo() + "出圈");
first = first.getNext();
helper.setNext(first);
}
System.out.println("最后留在圈中的小孩是" + first.getNo());
}
}
public class Josephus {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(5);
circleSingleLinkedList.list();
System.out.println("-------------------------------");
circleSingleLinkedList.outBoy(1,2,5);
}
}