一、单链表是什么?
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
现有一包糖果,班上共有三十六名同学,从第3个人数开始,每两个发两个糖果,问最后哪位同学没有糖果?请用程序计算出来。
创建NewBoy类,作为一个节点,next指向下一个节点
class NewBoy{
private Integer no;
private NewBoy next;
public NewBoy(int no){
this.no = no;
}
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public NewBoy getNext() {
return next;
}
public void setNext(NewBoy next) {
this.next = next;
}
}
编写主方法main,调用方法去实现
public static void main(String[] args) {
//Todo 现有一包糖果,班上共有三十六名同学,从第3个人数开始,每两个发两个糖果,最后一名没有糖果,问最后哪位同学没有糖果?
CircleSingleLinked c = new CircleSingleLinked();
c.add(36);//创建单链表
c.show();//遍历单链表
c.countNewBoy(3,2,36);//计算哪位同学没有糖果
}
方法实现
class CircleSingleLinked{
NewBoy first = new NewBoy(-1);
public void add(int num){
//Todo 创建链表
NewBoy curBoy = null;
for (int i= 1;i<=num;i++){
NewBoy boy = new NewBoy(i);
//第一位同学将作为头结点
if (i==1){
first = boy;
first.setNext(first);
curBoy = boy;
}else{
//后面的同学走这边
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;
}
System.out.printf("-------> 第%d个小孩添加成功\n",i);
}
}
public void show(){
//Todo 遍历链表
int i = 0;
NewBoy newBoy = first;
while (true){
i++;
System.out.printf("遍历现有同学------> 第%d同学\n",newBoy.getNo());
if (newBoy.getNext()==first){
System.err.printf("共有%d个小孩\n",i);
break;
}
newBoy = newBoy.getNext();
}
}
//根据用户的输入,计算出小孩节点出圈的顺序
/*
openNo表示从第几个同学开始数数
share表示每几个发一次糖果
sum表示最初有多少同学在圈
*/
public void countNewBoy(int openNo,int share,int sum){
//Todo 计算没有得到糖果的为第几位
if (first == null || openNo < 1 || openNo > sum){
System.out.println("参数输入有误,请重新输入!");
return;
}
NewBoy newBoy = first;
while (true){
//遍历节点,事先指向最后节点
if (newBoy.getNext() == first){
break;
}
newBoy = newBoy.getNext();
}
//从第几个同学开始数数,将开始的同学提到第一位
for (int i = 0;i<openNo-1;i++){
first = first.getNext();
newBoy = newBoy.getNext();
}
while (true){
//圈中只剩一个节点,将得出谁没有得到糖果
if (newBoy==first){
System.err.printf("第%d位没有得到糖果\n",first.getNo());
break;
}
//计算下一位得到糖果的同学
for(int i = 0;i<share - 1;i++){
first = first.getNext();
newBoy = newBoy.getNext();
}
System.out.printf("第%d位同学得到糖果\n",first.getNo());
//这时让得到糖果的同学出圈
first = first.getNext();
newBoy.setNext(first);
}
}
}
反转链表,用上面方法去调,有什么看不懂的欢迎来讨论
//Todo 反转链表
public void reverseList(){
NewBoy boy = null;
NewBoy newBoy = first;
while (true){
//遍历节点,事先指向最后节点
if (newBoy.getNext() == first){
break;
}
newBoy = newBoy.getNext();
}
while (newBoy!=null){
NewBoy next = newBoy.getNext();
newBoy.setNext(boy);
boy = newBoy;
newBoy = next;
}
first = boy;
show();
}