介绍
data
域,next
域:指向下一个节点实际应用
head
头节点的单向链表实现–水浒英雄排行榜管理。head
之后代码
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;
}
//重写toString方法,方便输出
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
单向链表类设计
class SingleList{
//这里直接初始化了头节点
private HeroNode head = new HeroNode(0,"","");
}
//添加英雄到链表尾
public void add(HeroNode node){
HeroNode cur = head;
while(cur.next != null){
cur = cur.next;
}
cur.next = node;
}
head
之后 //添加英雄到head后
public void addHead(HeroNode node){
//判断一下传入节点是否为空
if(node == null){
System.out.println("传入节点为空");
return;
}
node.next = head.next;
head.next = node;
}
//按照序号添加
public void addByOrder(HeroNode node){
if(node == null){
System.out.println("传入节点为空");
return;
}
HeroNode cur = head;
while(cur.next != null){
if(cur.next.no > node.no){
node.next = cur.next;
cur.next = node;
return;
}else if(cur.next.no == node.no){
System.out.println("编号已存在,不能添加");
return;
}else {
cur = cur.next;
}
}
}
//删除指定序号的节点
public void del(int no){
if(no < 1){
System.out.println("输入编号不合理");
return;
}
HeroNode cur = head;
while(cur.next != null){
if(cur.next.no == no){
cur.next = cur.next.next;
return;
}else {
cur = cur.next;
}
}
System.out.println("链表中没有这个编号");
}
//查找链表倒数第k个节点
public HeroNode findLastIndexNode(HeroNode head,int k){
HeroNode cur = head;
int size = size(head);
if(k <= 0 || k > size){ //校验k是否合理
return null;
}
for (int i = 0; i < size - k; i++) {
cur = cur.next;
}
return cur.next;
}
//返回头节点
public HeroNode getHead() {
return head;
}
//打印链表
public void list(){
if(head.next == null){
System.out.println("链表为空");
return;
}
HeroNode temp = head.next;
while (temp != null){
System.out.println(temp);
temp = temp.next;
}
}
//反转链表
public void reverseList(){
HeroNode pre = null;
HeroNode cur = head.next;
HeroNode next = null;
while (cur != null){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
head.next = pre;
}
//逆序打印
public void reversePrint(){
Stack<HeroNode> stack = new Stack<>();
HeroNode temp = head.next;
while(temp != null){
stack.push(temp);
temp = temp.next;
}
while (!stack.isEmpty()){
System.out.println(stack.pop());
}
}
//得到链表的长度
public int size(HeroNode head){
HeroNode cur = head;
int size = 0;
while(cur.next != null){
cur = cur.next;
size++;
}
return size;
}
//根据序号找到要修改的英雄节点进行修改
public void update(HeroNode node){
HeroNode cur = head;
while (cur.next != null){
if(cur.next.no == node.no){
cur.next.name = node.name;
cur.next.nickname = node.nickname;
return;
}
cur = cur.next;
}
System.out.println("更新失败");
}
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode newHead = new ListNode(-1);
ListNode tmp = newHead;
while(list1 != null && list2 != null){
if(list1.val < list2.val){
tmp.next = list1;
list1 = list1.next;
tmp = tmp.next;
}else{
tmp.next = list2;
list2 = list2.next;
tmp = tmp.next;
}
}
if(list1 != null){
tmp.next = list1;
}
if(list2 != null){
tmp.next = list2;
}
return newHead.next;
}
}
测试代码
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, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "a?", "buzhidao");
SingleList singleLinkedList = new SingleList();
singleLinkedList.add(hero1);
singleLinkedList.add(hero5);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero3);
singleLinkedList.addByOrder(hero2);
singleLinkedList.list();
System.out.println("删除3后");
singleLinkedList.del(3);
singleLinkedList.list();
System.out.println("反向输出");
singleLinkedList.reversePrint();
System.out.println("反转");
singleLinkedList.reverseList();
singleLinkedList.list();
System.out.println("查找倒数第二个节点");
System.out.println(singleLinkedList.findLastIndexNode(singleLinkedList.getHead(),2));
System.out.println("更新1号节点");
HeroNode hero6 = new HeroNode(1, "shua", "wocao");
singleLinkedList.update(hero6);
singleLinkedList.list();
}
和单向链表类似,只不过多一个前置节点
public class doubleLinkedListDemo {
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, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "a?", "buzhidao");
doubleLinkedList doubleLinkedList = new doubleLinkedList();
doubleLinkedList.add(hero1);
doubleLinkedList.add(hero2);
doubleLinkedList.add(hero3);
doubleLinkedList.add(hero4);
doubleLinkedList.add(hero5);
doubleLinkedList.list();
System.out.println("删除5");
doubleLinkedList.del(5);
doubleLinkedList.list();
System.out.println("修改3");
doubleLinkedList.update(new HeroNode(3,"wocao","ss"));
doubleLinkedList.list();
}
}
//双向链表类
class doubleLinkedList{
private HeroNode head = new HeroNode(0,"","");
//遍历
public void list(){
HeroNode temp = head;
while(temp.next != null){
System.out.println(temp.next);
temp = temp.next;
}
}
//添加
public void add(HeroNode heroNode){
HeroNode temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
//修改
//更新节点
public void update(HeroNode newHeroNode){
HeroNode cur = head;
while(cur.next != null){
if(cur.next.no == newHeroNode.no){
cur.next.name = newHeroNode.name;
cur.next.nickname = newHeroNode.nickname;
return;
}
cur = cur.next;
}
System.out.println("更新失败");
}
//删除
public void del(int no){
HeroNode temp = head.next;
while (temp != null){
if(temp.no == no){
temp.pre.next = temp.next;
if(temp.next != null){
temp.next.pre = temp.pre;
}
return;
}
temp = temp.next;
}
System.out.println("删除失败");
}
}
//英雄类
class HeroNode{
public int no;
public String name;
public String nickname;
public HeroNode pre;
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 + '\'' +
'}';
}
}
应用:约瑟夫问题
创建环形链表思路
出圈思路
代码实现
package linkedList.circleLinkedList;
public class circleLinkedListDemo{
public static void main(String[] args) {
CircleLinkedList circleLinkedList = new CircleLinkedList();
circleLinkedList.addBoy(5);
circleLinkedList.countBoy(1,2,5);
}
}
//环形链表
class CircleLinkedList{
private Boy first = null;
public void addBoy(int nums){
if(nums < 1){
System.out.println("输入的值不对");
}
Boy curBoy = first;
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);
curBoy = curBoy.getNext();
curBoy.setNext(first);
}
}
}
//遍历环形链表
public void showBoy(){
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();
}
}
public void countBoy(int startNo,int countNum,int nums){
Boy helper = first;
while (helper.getNext() != first){
helper = helper.getNext();
}
for (int i = 0; i < startNo - 1; i++) {
first = first.getNext();
helper = helper.getNext();
}
while (true){
if(helper == first){
//圈中只剩下一个小孩
break;
}
for (int i = 0; i < countNum - 1; i++) {
first = first.getNext();
helper = helper.getNext();
}
System.out.println("出圈小孩为:"+first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.println("剩下的小孩为:"+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;
}
}