一.单链表
package com.bzw.linkedlist; import java.util.Stack; public class SingleLinkedList { public static void main(String[] args) { Hero hero1 = new Hero(1, "宋江", "及时雨"); Hero hero2 = new Hero(2, "卢俊义", "玉麒麟"); Hero hero3 = new Hero(3, "吴用", "智多星"); Hero hero4 = new Hero(4, "林冲", "豹子头"); Hero hero5 = new Hero(5, "小卢", "玉麒麟~~"); Hero hero6 = new Hero(6, "小卢", "玉麒麟~~"); SingleLinked singleLinked = new SingleLinked(); SingleLinked singleLinked1 = new SingleLinked(); // singleLinked.addHero(hero2); // singleLinked.addHero(hero3); // singleLinked.addHero(hero4); // singleLinked.addHero(hero1); singleLinked.addHeroByOrder(hero3); singleLinked.addHeroByOrder(hero2); singleLinked1.addHeroByOrder(hero4); singleLinked.addHeroByOrder(hero1); singleLinked.addHeroByOrder(hero5); singleLinked1.addHeroByOrder(hero6); // singleLinked.addHeroByOrder(hero4); // singleLinked.showHero(); // singleLinked.update(hero5); // singleLinked.delete(hero4); singleLinked.showHero(); System.out.println(); singleLinked1.showHero(); //练习题 // System.out.println("有效结点个数"+getLength(singleLinked.getHead())); // // System.out.println(findNode(singleLinked.getHead(),4)); // reverseLinkedList(singleLinked.getHead()); // singleLinked.showHero(); // reversePrint(singleLinked.getHead()); jojnLinkedList(singleLinked.getHead(), singleLinked1.getHead()); System.out.println(); singleLinked.showHero(); } //链表有效结点个数 public static int getLength(Hero head) { if (head.next == null) { System.out.println("链表为空"); return 0; } Hero temp = head.next; int count = 0; while (temp != null) { count++; temp = temp.next; } return count; } //查询倒数第k个结点 public static Hero findNode(Hero head, int index) { if (head.next == null) { System.out.println("空链表"); } int size = getLength(head); Hero temp = head.next; if (index < 0 || index > size) { return null; } for (int i = 0; i < size - index; i++) { temp = temp.next; } System.out.println("倒数第" + index + "个结点:"); return temp; } //反转链表 public static void reverseLinkedList(Hero head) { if (head.next == null) { System.out.println("空链表"); } Hero temp = head.next; Hero next = null; //temp 结点的下一个(非常重要的一个指针(变量),不用这个变量把temp.next存起来的话,单链表就会断掉) Hero newHead = new Hero(0, "", ""); while (temp != null) { next = temp.next; temp.next = newHead.next; //temp的下一个结点指向新链表的最前端。(其实就是将新加入的结点和后面的结点连接起来) newHead.next = temp; temp = next; } head.next = newHead.next; } //逆序打印(利用栈的先进后出特点,不破坏原链表的结构) public static void reversePrint(Hero head) { if (head.next == null) { System.out.println("链表为空"); } Stack<Hero> stack = new Stack<>(); Hero temp = head.next; while (temp != null) { stack.push(temp); temp = temp.next; } while (stack.size() > 0) { System.out.println(stack.pop()); } } //将两个链表按顺序合并成一个链表(练习) public static void jojnLinkedList(Hero head1, Hero head2) { Hero temp1 = head1.next; Hero temp2 = head2.next; Hero temp3 = null; //暂存temp1.next;如果不用一个变量暂存的话,后面temp1.next已经指向了其他的值,就不是我们想要的结果。 while (temp1 != null && temp2 != null) { if(temp1.next == null){ temp1.next = temp2; break; } if (temp2.no > temp1.no && temp2.no < temp1.next.no) { head2.next = temp2.next; temp3 = temp1.next; temp1.next = temp2; temp2.next = temp3; temp1 = temp1.next; temp2 = head2.next; } else temp1 = temp1.next; } } } /* private 私有 只能在同一个类中才能访问到 friendly(默认) 同一个包下可以访问(子孙类也只能在同一个包下) protected 保护 同一个包下可以访问(其他包的继承了用protected修饰的,其子孙类也可以继承,即其他包的子孙类也可以访问) public 公共 在哪都能访问到 */ class Hero{ public int no; public String name; public String nickName; public Hero next; public Hero(int no,String name,String nickName){ this.no = no; this.name = name; this.nickName = nickName; } @Override public String toString() { return "Hero{" + "no=" + no + ", name=‘" + name + ‘\‘‘ + ", nickName=‘" + nickName + ‘\‘‘ + ‘}‘; } } class SingleLinked{ Hero head = new Hero(0,"","");//头结点 public Hero getHead() { return head; } //直接添加在链表尾部(不考虑顺序) public void addHero(Hero heroNode){ Hero temp = head; //因为是单链表,头结点不能动,否则会找不到链表。所以利用一个temp结点来完成操作 while(true){ if(temp.next == null){ break; } temp = temp.next; } temp.next = heroNode; } //按顺序添加 public void addHeroByOrder(Hero heroNode){ Hero temp = head; while (true){ if(temp.next == null){ temp.next = heroNode; break; } else if(heroNode.no < temp.next.no){ heroNode.next = temp.next; temp.next = heroNode; break; } if(heroNode.no == temp.next.no){ System.out.printf("结点%d已存在,插入失败\n",heroNode.no); break; } temp = temp.next; } } public void delete(Hero heroNode){ if(head.next == null){ System.out.println("链表为空"); return; } Hero temp = head; // temp 是等于head 还是等于 head.next 。具体需要具体分析 Boolean flag = false; while (true){ if(temp.next == null){ break; } if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ temp.next = temp.next.next; } else { System.out.println("没有你要删除的结点"); } } public void update(Hero heroNode){ Hero temp = head.next ; if(temp == null){ System.out.println("链表为空,请先插入数据"); return; } while (true){ if(temp == null ){ System.out.println("没有该结点"); break; } if(temp.no == heroNode.no){ temp.name = heroNode.name; temp.nickName = heroNode.nickName; break; } temp = temp.next; } } public void showHero(){ if(head.next == null){ System.out.println("链表为空"); } Hero temp = head.next; while (true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
二.双向链表
package com.bzw.linkedlist; public class DoubleLinked { public static void main(String[] args) { Hero2 hero1 = new Hero2(1, "宋江", "及时雨"); Hero2 hero2 = new Hero2(2, "卢俊义", "玉麒麟"); Hero2 hero3 = new Hero2(3, "吴用", "智多星"); Hero2 hero4 = new Hero2(4, "林冲", "豹子头"); Hero2 hero5 = new Hero2(2, "小卢", "玉麒麟~~"); DoubleLinkedList doubleLinkedList = new DoubleLinkedList(); // doubleLinkedList.add(hero1); // doubleLinkedList.add(hero2); // doubleLinkedList.add(hero3); // doubleLinkedList.add(hero4); doubleLinkedList.addByOrder(hero1); doubleLinkedList.addByOrder(hero4); doubleLinkedList.addByOrder(hero2); doubleLinkedList.addByOrder(hero3); doubleLinkedList.delete(hero3); // doubleLinkedList.update(hero5); // doubleLinkedList.delete(hero5); doubleLinkedList.showLinked(); } } class Hero2{ public int no; public String name; public String nick; public Hero2 pre; public Hero2 next; public Hero2(int no,String name,String nick){ this.no = no; this.name = name; this.nick = nick; } @Override public String toString() { return "Hero2{" + "no=" + no + ", name=‘" + name + ‘\‘‘ + ", nick=‘" + nick + ‘\‘‘ + ‘}‘; } } class DoubleLinkedList{ Hero2 head = new Hero2(0,"",""); public Hero2 getHead() { return head; } //遍历(不要小看任何一个操作,思路稍微有点错就达不到理想效果) public void showLinked(){ if(head.next == null){ System.out.println("链表为空"); } Hero2 temp = head.next; while (true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } //添加(直接添加在最后) public void add(Hero2 newHeroNode) { Hero2 temp = head; while (true) { if (temp.next == null){ break; } temp = temp.next; } temp.next = newHeroNode; newHeroNode.pre = temp; } //添加(按顺序添加) public void addByOrder(Hero2 newHeroNode){ Hero2 temp = head; while (true){ if (temp.next == null){ temp.next = newHeroNode; newHeroNode.pre = temp; break; } if (newHeroNode.no > temp.no && newHeroNode.no < temp.next.no ){ temp.next.pre = newHeroNode; newHeroNode.next = temp.next; temp.next = newHeroNode; newHeroNode.pre = temp; break; } else if (newHeroNode.no < temp.no && newHeroNode.no >temp.pre.no){ newHeroNode.pre = temp.pre; temp.pre.next = newHeroNode; temp.pre = newHeroNode; newHeroNode.next = temp; break; } else if (newHeroNode.no == temp.no){ System.out.println("结点已存在"); } temp = temp.next; } } //修改 public void update(Hero2 newHeroNode){ Hero2 temp = head.next; if (temp == null){ System.out.println("空链表"); } while (true){ if (temp.no == newHeroNode.no){ temp.name = newHeroNode.name; temp.nick = newHeroNode.nick; break; } temp = temp.next; } } //删除(双向链表的删除和单链表有所不同。单链表删除时是找到要删除结点的前一个结点, // 而双向链表就是找到要删除的这个结点。) public void delete(Hero2 heroNode){ Hero2 temp = head.next; while (true){ if (temp.no == heroNode.no){ temp.pre.next = temp.next; temp.next.pre = temp.pre; break; } temp = temp.next; } } }
三.循环链表(约瑟夫问题)
package com.bzw.linkedlist; //约瑟夫环实现代码 public class RingLinkedList { public static void main(String[] args) { RingLinked ringLinked = new RingLinked(); ringLinked.add(5); ringLinked.show(); ringLinked.countBoy(1,2,5); } } 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; } @Override public String toString() { return "Boy{" + "no=" + no + ‘}‘; } } class RingLinked{ Boy first = null; //添加(这里是实现约瑟夫环问题代码,实现环形链表可以设头结点也可以不设) public void add(int nums) { Boy temp = null; for (int i = 1; i <= nums; i++) { Boy boy = new Boy(i); if (i == 1) { first = boy; first.setNext(first); temp = first; } else { temp.setNext(boy); boy.setNext(first); temp = boy; } } } //遍历 public void show(){ if (first == null){ System.out.println("空链表"); return; } Boy temp = first; while (true){ System.out.println(temp); if (temp.getNext() == first){ break; } temp = temp.getNext(); } } //出圈顺序 public void countBoy(int k,int m,int n){ Boy helper = first;//始终跟在first后面,用于删除结点 while (true){ if (helper.getNext() == first) break; else { helper = helper.getNext();//helper = helper.next; } } //移动到开始报数的那个位置 for (int i=0;i<k-1;i++){ first = first.getNext(); helper = helper.getNext(); } while (true){ //圈中只剩一个结点 if (helper == first){ break; } for (int i=0;i<m-1;i++){ first = first.getNext(); helper = helper.getNext(); } System.out.println("出圈结点为:" + first.getNo()); first = first.getNext(); helper.setNext(first);//helper.next = first; } System.out.println("最后一个结点为:"+helper.getNo()); } }
原文:https://www.cnblogs.com/tiger2048/p/14091641.html