链表是有序的列表,但它在内存中是这样存储的。
1、链表是以节点的方式来存储。
2、每个节点包括data域,next域指向下雨个节点。
3、各个节点不一定是连续存储的。
4、链表分带头节点的链表和不带头结点的链表。
工作案例:
public class SIngleLinkedListDemo {
public static void main(String[] args) {
SingleLinkedList singleLinkedList = new SingleLinkedList();
HeroNode heroNode = new HeroNode(23, "james");
HeroNode heroNode1 = new HeroNode(11, "欧文");
//singleLinkedList.add(heroNode);
//singleLinkedList.add(heroNode1);
singleLinkedList.addByNo(heroNode);
singleLinkedList.addByNo(heroNode1);
singleLinkedList.modify(20, "庞大大");
singleLinkedList.show();
singleLinkedList.del(20);
singleLinkedList.show();
}
}
class SingleLinkedList{
private HeroNode head=new HeroNode(0, "");
public static HeroNode temp;
public SingleLinkedList() {
temp = head;
}
//按照编号,插入指定位置
public void addByNo(HeroNode node){
HeroNode t =head;
while (true){
if (t.next!=null) {
if (t.next.no > node.no) {
node.next = t.next;
t.next = node;
break;
} else if (t.next.no == node.no) {
System.out.println("该球员已存在");
break;
}else {
add(node);
System.out.println("已填到末尾");
break;
}
}else {
add(node);
System.out.println("已填到末尾");
break;
}
}
}
public void del(int no){
boolean flag =false;
HeroNode t =head;
if (t.next!=null){
while (true){
if (t.next!=null) {
if (t.next.no == no) {
flag = true;
break;
}else {
t=t.next;
}
}else {
break;
}
}
if (flag) {
t.next = t.next.next;
}else {
System.out.println("没有该号码");
}
}else {
System.out.println("链表为空");
}
}
//直接在末尾添加
public void add(HeroNode node){
temp.next=node;
temp=node;
}
//修改,姓名
public void modify(int no,String name){
if (head.next==null){
System.out.println("链表为空");
}else {
HeroNode t =head.next;
while (true){
if (t==null){
System.out.println("没有这个号码,我来帮你加上");
addByNo(new HeroNode(no,name));
break;
}
if (t.no==no){
t.name=name;
break;
}
t=t.next;
}
}
}
public void show(){
if (head.next==null){
System.out.println("链表为空");
}else {
HeroNode t =head;
while (true){
if (t.next==null){
break;
}else {
t=t.next;
System.out.println(t.toString());
}
}
}
}
}
class HeroNode{
public int no;
public String name;
public HeroNode next;
public HeroNode(int no, String name) {
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}
双向链表
约瑟夫环
单向环形链表实现约瑟夫环:
1、创建单向环形链表:
- 1、先创建第一个节点,让first指向该节点,并形成环形
- 2、后面当我们每创建一个新节点,就把该节点加入到已有的环形链表中。
2、遍历环形链表 - 1、先让一个辅助指针curboy,指向first节点
- 2、然后通过while循环遍历该环形链表即可,知道curboy.next==first即可。
import java.util.Scanner;
/*
约瑟夫环
*/
public class Josephu {
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int num = scanner.nextInt();//总人数
int m =scanner.nextInt();//跳出个数
int index =scanner.nextInt();//起始点
list list = new list();
for (int i = 1; i <= num; i++) {
list.add(i);
}
list.josePhu(m, 1);
System.out.println();
}
}
class list{
Boy head=new Boy(-1);
Boy first=head;
Boy helper =head;
public void add(int i){
if (first.no==-1){
head.setNo(i);
}else {
Boy boy =new Boy(i);
helper.next=boy;
helper=helper.next;
helper.setNext(first);
}
}
public void josePhu(int m,int index) {
if (m<1){
return;
}
//开始前先移动index-1
for (int i = 0; i < index - 1; i++) {
helper=helper.getNext();
first=first.getNext();
}
while (true){
for (int i = 0; i < m - 1; i++) {
helper=helper.getNext();
first=first.getNext();
}
System.out.println(first.getNo());
first=first.getNext();
helper.setNext(first);
if (helper==first){
System.out.println(first.getNo());
break;
}
}
}
}
class Boy{
int no;
Boy next;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
下面是牛客老哥做约瑟夫环问题的两种方法
第一种:
第二种: