1、单向链表
//节点的定义
public class GoodsNode {
public String name;
public double price;
//指向下一个节点的指针
public GoodsNode next;
//构造方法
public GoodsNode() {
}
public GoodsNode(String name, double price) {
this.name = name;
this.price = price;
}
}
//链表的常见操作
public class MyLinkList {
//头结点
private GoodsNode head = new GoodsNode("", 0);
//链表的长度
private int lenth = 0;
//获取头结点
public GoodsNode getHead() {
return head;
}
//获取链表长度
public int getLenth() {
return lenth;
}
//添加添加节点的方法,使用尾插法
public void add(GoodsNode node) {
GoodsNode temp = this.head;
//通过头结点找到最后一个节点
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
lenth++;
}
//插入节点,参数1表示要插入的节点,参数2表示要插入的索引位置
public void insert(GoodsNode node, int index) {
GoodsNode temp = this.head;
//首先对错误索引进行处理
if (index <= 0 || index > this.lenth) {
throw new RuntimeException("索引有误!");
} else if (index == lenth) {
//通过头结点找到最后一个节点
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
lenth++;
} else {
while (index > 0) {
temp = temp.next;
index--;
}
//记录当前节点的下一个节点
GoodsNode next = temp.next;
//然后将当前节点的下一个节点指向新的节点
temp.next = node;
//然后将新节点的next域指向刚才记录的next值
node.next = next;
//长度自加
lenth++;
}
}
//通过商品的价值从小往后增加,
public void addOrder(GoodsNode node) {
GoodsNode temp = this.head;
while (true) {
//如果传入节点的价格大于当前索引下节点的价格,那么则结束循环
if (node.price >= temp.price || temp.next == null) {
break;
}
temp = temp.next;
}
//如果索引到了最后一个节点,则直接将最后一个节点的next域设置为新加入的节点
if (temp.next == null) {
//必须要比最后一个节点的价格高才可以添加到链表中
if(node.price >= temp.price){
temp.next = node;
//长度自增
lenth++;
}
} else {
//如果不是最后一个节点,那么就需要首先记录当前节点的next域中的值
GoodsNode next = temp.next;
//然后将当前节点的下一个节点指向新的节点
temp.next = node;
//然后将新节点的next域指向刚才记录的next值
node.next = next;
//长度自加
lenth++;
}
}
//输出列表的方法
public void showLinkList(){
GoodsNode node = head.next;
while (node != null){
System.out.println("商品名称为:" + node.name + "\t商品价格为:" + node.price);
node = node.next;
}
}
}
//测试类
public class Test1 {
public static void main(String[] args) {
MyLinkList list = new MyLinkList();
//创建三个节点
GoodsNode node1 = new GoodsNode("华为",4399);
GoodsNode node2 = new GoodsNode("一加",5999);
GoodsNode node3 = new GoodsNode("步步高",5399);
//调用添加节点的方法
list.add(node1);
list.add(node2);
list.add(node3);
//输出信息
list.showLinkList();
}
}
输出结果:
商品名称为:华为 商品价格为:4399.0 商品名称为:一加 商品价格为:5999.0 商品名称为:步步高 商品价格为:5399.0
2、双向链表
//节点的定义
public class DoubleGoodsNode {
public int id;
public String name;
public double price;
//指向下一个节点
public DoubleGoodsNode next;
//指向下一个节点
public DoubleGoodsNode previous;
public DoubleGoodsNode() {
}
public DoubleGoodsNode(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
}
//对链表的操作
/**
* 双向链表
*/
public class DoubleLinkList {
private DoubleGoodsNode head = new DoubleGoodsNode(0, "", 0.0);
//双向链表的长度
private int lenth;
//获取链表长度
public int getLenth() {
return lenth;
}
//尾插法
public void addLast(DoubleGoodsNode node) {
//获取头结点
DoubleGoodsNode temp = this.head;
//遍历到最后一个节点
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
node.previous = temp;
lenth++;
}
//任意索引位置插入节点
public void insertData(DoubleGoodsNode node, int index) {
//获取头结点
DoubleGoodsNode temp = this.head;
//首先对错误索引进行处理
if (index <= 0 || index > this.lenth) {
throw new RuntimeException("索引有误!");
}else if(index == lenth){ //相当于直接插在末尾
addLast(node);
}else {
while (index > 0) {
temp = temp.next;
index--;
}
//记录当前节点的下一个值
DoubleGoodsNode next = temp.next;
temp.next = node;
node.previous = temp;
node.next = next;
next.previous = node;
lenth++;
}
}
//遍历链表
public void showDoubleList() {
//获取头节点
DoubleGoodsNode node = head.next;
while (node != null) {
System.out.println("商品ID为:" + node.id + "\t商品名称为:" + node.name + "\t\t商品价格为:" + node.price);
node = node.next;
}
}
}
//测试类
public class Test2 {
public static void main(String[] args) {
//创建几个节点
DoubleGoodsNode node1 = new DoubleGoodsNode(1,"Huawei",6499);
DoubleGoodsNode node2 = new DoubleGoodsNode(2,"Sanxing",6899);
DoubleGoodsNode node3 = new DoubleGoodsNode(3,"Honor",6499);
//创建双向链表
DoubleLinkList list = new DoubleLinkList();
//插入节点
list.addLast(node1);
list.addLast(node2);
list.addLast(node3);
//输出链表
list.showDoubleList();
System.out.println("--------------------------");
//利用索引插入节点
DoubleGoodsNode node4 = new DoubleGoodsNode(3,"Leshi",6899);
list.insertData(node4,3);
list.showDoubleList();
}
}
输出结果:
商品ID为:1 商品名称为:Huawei 商品价格为:6499.0
商品ID为:2 商品名称为:Sanxing 商品价格为:6899.0
商品ID为:3 商品名称为:Honor 商品价格为:6499.0
--------------------------
商品ID为:1 商品名称为:Huawei 商品价格为:6499.0
商品ID为:2 商品名称为:Sanxing 商品价格为:6899.0
商品ID为:3 商品名称为:Honor 商品价格为:6499.0
商品ID为:3 商品名称为:Leshi 商品价格为:6899.0
进程已结束,退出代码0
3、利用循环链表解决约瑟夫问题
约瑟夫问题:设编号为1,2…,n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
//定义节点类
public class Boy {
private int id;
private Boy next;
public Boy() {
}
public Boy(int age) {
this.id = age;
}
/**
* 获取
* @return age
*/
public int getId() {
return id;
}
/**
* 设置
* @param age
*/
public void setId(int age) {
this.id = age;
}
/**
* 获取
* @return next
*/
public Boy getNext() {
return next;
}
/**
* 设置
* @param next
*/
public void setNext(Boy next) {
this.next = next;
}
}
//定义双向链表并且解决约瑟夫问题的类
public class RingList {
private Boy first = new Boy(-1);
//环形链表的长度
private int lenth = 0;
//设置指定长度的环形链表
public void addBoy(int num) {
if (num < 1) {
System.out.println("数量有误!");
return;
}
Boy temp = null;
for (int i = 1; i <= num; i++) {
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
first.setNext(first);
temp = first;
lenth++;
} else {
temp.setNext(boy);
boy.setNext(first);
temp = boy;
lenth++;
}
}
}
//查看环形链表中的数据
public void showRingList() {
if (first == null) {
System.out.println("链表为空!");
return;
}
Boy boy = first;
while (boy.getNext() != first) {
System.out.println("boy的ID为:" + boy.getId());
boy = boy.getNext();
}
}
//解决约瑟夫问题
public void yueSeFu(int k, int m) {
if (first == null || k < 1 || m > lenth) {
System.out.println("输出数据有误或者链表数据为空!");
return;
}
//最后一个节点
Boy end = first;
while (true) {
end = end.getNext();
if (end.getNext() == first) {
break;
}
}
//根据k值重新确定循环链表的起始位置
for (int i = 0; i < k - 1; i++) {
first = first.getNext();
end = end.getNext();
}
//找到出列的孩子
while (true) {
if (end == first) { //表示只剩下了最后一个元素
System.out.println("小孩" + first.getId() + "出列!");
break;
} else {
for (int i = 0; i < m - 1; i++) {
first = first.getNext(); //遍历结束后first指向的值就是需要出列的数据
end = end.getNext();
}
}
System.out.println("小孩" + first.getId() + "出列!");
first = first.getNext();
end.setNext(first);
}
}
}
标签:node,temp,public,链表,GoodsNode,next,节点
From: https://blog.51cto.com/u_15433911/7472037