1将链表反转,再遍历输出,不推荐,会打乱链表原有顺序
2遍历链表,把值压入一个栈,再把栈的数据输出
3用for循环遍历链表,从最后一位开始,逆序输出
package 算法.单向链表和双向链表的创建和遍历;
import java.util.Stack;
public class LinkedListDemo {
public static void main(String[] args) {
HeroNode node1 = new HeroNode(1,"宋江");
HeroNode node2 = new HeroNode(2,"卢俊义");
HeroNode node3 = new HeroNode(3,"吴用");
HeroNode node4 = new HeroNode(4,"林冲");
HeroNode node5 = new HeroNode(4,"林");
HeroNode node6 = new HeroNode(6,"456");
LinkList list = new LinkList();
list.add(node1);
list.add(node2);
list.add(node4);
list.addByNo(node3);
list.show();
System.out.println("");
list.reversePrint(list.getHead());
list.reversePrint2(list.getHead());
}
}
//创建一个链表类
class LinkList{
//先初始化一个头节点
private HeroNode head= new HeroNode(0,"");
//添加结点
//如果不考虑编号
//找到链表的尾指针,指向添加的结点
public HeroNode getHead() {
return head;
}
public void add(HeroNode node){
HeroNode temp =head;
while (true){
if(temp.next==null){
break;
}
temp=temp.next;
}
temp.next=node;
}
//第二种添加英雄的方式
//根据排名将英雄加入指定的位置,如果有这个排名。则添加失败
public void addByNo(HeroNode node){
//辅助指针指向要添加的位置的上一个结点
HeroNode temp =head;
//标志当前的添加的编号是否存在
boolean flag= false;
while (true){
if (temp.next==null){
//temp已经在链表的最后
//当前结点指向要添加的结点
break;
}
if(temp.next.no>node.no){
//如果下一个结点的编号大于要添加的结点
//那就添加到当前位置
break;
}else if(temp.next.no==node.no){
flag=true;
break;
}
temp=temp.next;
}
//判断是否要添加的编号已经存在
if(flag){
System.out.println("编号已经存在");
}else {
node.next=temp.next;
temp.next=node;
}
}
//根据no修改结点的信息,no不能修改,否则会打乱编号排序,修改no应该删除结点,再重新添加。
//根据newHeronode的no值来添加修改即可
public void update(HeroNode newHeroNode){
if(this.head.next==null){
System.out.println("链表为空");
return;
}
HeroNode temp = head.next;
boolean flag = false;
while(true){
if(temp==null){
break;
}
if(temp.no==newHeroNode.no){
flag=true;
break;
}
temp=temp.next;
}
if(flag==true){
temp.name=newHeroNode.name;
}else {
System.out.println("没有找到要修改的结点");
}
}
//根据no删除结点
public void del(int no){
HeroNode temp = head;
while (head==null){
System.out.println("链表为空,无法删除");
return;
}
while(true){
if(temp.next==null){//要写在temp.next.no==nod判断语句之前,不然当temp是表尾会发生空指针异常
System.out.println("不存在指定删除的结点");
break;
}
if(temp.next.no==no){
temp.next=temp.next.next;
break;
}
temp=temp.next;
}
}
//遍历链表
public void show(){
HeroNode temp = head.next;//本例中头节点不存放数据
boolean flag=false;//flag标志添加的编号是否存在
if (head.next==null){
System.out.println("链表为空");
return;
}
while (true){
if(temp==null){
break;
}
System.out.println(temp);
temp=temp.next;
}
}
//输出单链表中倒数第k个结点,输入参数,头节点,倒数第k个参数
public HeroNode findK(HeroNode head,int k){
int length = 0;
HeroNode temp = head;
if(head.next==null){
throw new RuntimeException("单链表为空");
}
while (temp.next!=null){
length++;
temp=temp.next;
}
temp=head.next;
for (int i = 0; i <length-k ; i++) {
temp=temp.next;
}
return temp;
}
//链表反转,传入参数,链表的头结点
public void reversetList(HeroNode head){
if(head.next==null||head.next.next==null){
return;
}
HeroNode cur = head.next;
HeroNode next=null;
HeroNode reverseHead=new HeroNode(0,"");
//遍历链表,每取出一个结点,就放在新结点的最前端
while (cur!=null){
//标记cur下一个,第四步用
next=cur.next;
//取出的cur进行头插法
cur.next=reverseHead.next;
reverseHead.next=cur;
cur=next;
}
head.next=reverseHead.next;
}
//逆序输出方法二 栈
public void reversePrint(HeroNode head){
if(head.next==null){
return;
}
Stack<HeroNode> stack = new Stack<>();
HeroNode cur = head.next;
while (cur!=null){
stack.push(cur);
cur=cur.next;
}
while (!stack.empty()){
System.out.println(stack.peek());
stack.pop();
}
}
//逆序方法三 for循环
public void reversePrint2(HeroNode head){
if(head.next==null){
return;
}
int length=0;
HeroNode cur = head.next;
while (cur!=null){
cur=cur.next;
length++;
}
for (int i = 0; i <length ; i++) {
HeroNode temp = head;
int j=0;
while (j<length-i){
temp=temp.next;
j++;
}
System.out.println(temp);
}
}
}
//结点类
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 + '\'' +
'}';
}
}