2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 四 数据结构与算法 (四)单向链表面试:将链表顺序倒过来

四 数据结构与算法 (四)单向链表面试:将链表顺序倒过来

时间:2021-11-21 21:16:36

相关推荐

四 数据结构与算法 (四)单向链表面试:将链表顺序倒过来

1.代码

1.将单向链表反向

/*** 反向设置链表* @param head 传入要反向的头节点*/public void reverseSetList(HeroNode head) {//判断链表是否可以反向,或没必要反向:null,或者链表长度为1,那么没有必要反向if (head.next==null||head.next.next==null) {System.out.println("链表长度为null或者长度为1,没有必要反向");return;}//长度可以反向//用来反向的辅助头节点HeroNode reverseHead=new HeroNode(0,"","");//当前节点HeroNode cur = head.next;//当前节点的下一个节点,为了不断链HeroNode curNext = null;//遍历队列while (cur != null) {curNext=cur.next;//为当前节点的下一个节点赋值,目的是保证链表不断裂cur.next=reverseHead.next;//当前节点的下一个指向赋值头节点的下一个reverseHead.next=cur;//为赋值节点的下一个赋值cur=curNext;//当前节点后移}head.next=reverseHead.next;//最后头节点指向反向节点的next}

2.全部代码:

package com.example.lib5.linkedList;public class SingleLinkedListDemo {public static void main(String[] args) {//进行测试//先创建节点HeroNode heroNode = new HeroNode(1, "唐三", "昊天宗");HeroNode heroNode1 = new HeroNode(2, "小舞", "十万年魂兽");HeroNode heroNode2 = new HeroNode(3, "宁荣荣", "七宝琉璃宗");HeroNode heroNode3 = new HeroNode(4, "千仞雪", "武魂殿");//创建链表,并加入节点MyLinkedList myLinkedList = new MyLinkedList();// myLinkedList.add(heroNode);// myLinkedList.add(heroNode3);// myLinkedList.add(heroNode1);// myLinkedList.add(heroNode2);//根据顺序来加入节点myLinkedList.addByOrder2(heroNode);myLinkedList.addByOrder2(heroNode3);myLinkedList.addByOrder2(heroNode1);myLinkedList.addByOrder2(heroNode2);// myLinkedList.addByOrder2(heroNode2);// //遍历节点myLinkedList.list();HeroNode heroNodeNew = new HeroNode(3, "海女斗罗", "海神岛");myLinkedList.update(heroNodeNew);myLinkedList.list();//对链表进行删除// myLinkedList.delete(3);myLinkedList.list();/*** 面试题*/System.out.println("面试题,获取链表的有效值:");System.out.println(myLinkedList.getLength(myLinkedList.getHead()));HeroNode lastIndexNode=myLinkedList.findLastIndexNode(myLinkedList.getHead(),2);System.out.println(lastIndexNode);//腾讯面试题,把链表倒过来:123变成321System.out.println("腾讯面试题,把链表倒过来:123变成321");myLinkedList.reverseSetList(myLinkedList.getHead());myLinkedList.list();}private static class HeroNode {private int no;private String name;private String background;private HeroNode next;//背景public HeroNode(int no, String name, String background) {this.no=no;this.name=name;this.background =background;}@Overridepublic String toString() {return "HeroNode{" +"no=" + no +", name='" + name + '\'' +", background='" + background + '\'' +'}';}}private static class MyLinkedList {//默认设置有一个头节点private HeroNode head=new HeroNode(0,"","");public HeroNode getHead() {return head;}public void add(HeroNode heroNode) {HeroNode temp=head;//遍历出最后一个节点while (true) {if (temp.next==null) {break;}//后移temp=temp.next;}//对最后一个节点进行赋值temp.next=heroNode;}public void list() {//判断链表是否为空,如果是空的话,就没有必要遍历if (head.next==null) {System.out.println("链表为空");return;}System.out.println("链表结果打印如下:");//因为头节点不能动,所以我们需要一个辅助遍历来遍历HeroNode temp = head.next;while (true) {//判断是否为最后一个节点if (temp==null) {break;}//输出节点的信息System.out.println(temp);//将temp后移,一定要小心temp=temp.next;}}/*** 下面的方法耦合性比较大,就是有什么就做什么。而addByOrder2里面的方法则是,分成两部分:获取状态,根据状态来进行逻辑处理,这样比较解耦,高内聚(统一处理)* @param heroNode*/public void addByOrder(HeroNode heroNode) {//判断链表是否为空链表,如果是空链表的话,就直接加入HeroNode temp =head;//链表不为空的情况//遍历获取链表比heroNode.no大的值的前一个while (true) {//如果链表存在了,就不添加进去if (temp.next==null) {temp.next=heroNode;break;}elseif (temp.next.no==heroNode.no) {System.out.println("链表已经存在了,无法在添加进去");break;}else//下面是获取比heroNode.no大的值,然后temp就是前一个if (temp.next.no>heroNode.no) {//先让heroNode的next指向比它大值得那个heroNode.next=temp.next;//再让上一个指向添加的值temp.next=heroNode;break;}else if (temp.next==null){temp.next=heroNode;break;}//如果不是的话,就后移,便于继续遍历temp=temp.next;}}/*** ,分成两部分:获取状态,根据状态来进行逻辑处理,这样比较解耦,高内聚(统一处理)* @param heroNode*/public void addByOrder2(HeroNode heroNode){//因为头节点不能动,因此我们仍然通过一个辅助指针来帮助找到添加的位置//要找到单链表的前一个,如果找到的是这个,那么久只能为这个赋值,HeroNode temp = this.head;boolean flag=false;while (true) {if (temp.next==null) {//说明是链表的最后一个了,直接添加即可break;}if (temp.next.no>heroNode.no) {break;}else if (temp.next.no==heroNode.no){//这个编号已经添加过了flag=true;break;}temp=temp.next;}//判断flag的值if (flag) {System.out.printf("准备插入的英雄编号 %d 已经存在了,不能加入\n",heroNode.no);}else {//插入得到链表中,temp的后面heroNode.next=temp.next;temp.next=heroNode;}}public void update(HeroNode heroNodeNew) {//判断链表是否为空if (head.next==null) {System.out.println("链表为空,无法进行修改,可以先添加");return;}//设置一个标记,true表示存在这个编号,false表示不存在这个编号boolean flag=false;HeroNode temp = head.next;while (true) {if (temp==null) {//表示链表为空System.out.println("链表已经遍历完了");flag=false;break;}//根据编号来确定是否有得修改if (temp.no==heroNodeNew.no) {flag=true;break;}//后移temp=temp.next;}if (flag==true) {//如果是存在就进行修改temp.name=heroNodeNew.name;temp.background=heroNodeNew.background;}else {System.out.println("不存在此编号,所以无法修改");}}public void delete(int no) {//判断链表是否为空if (head.next==null) {System.out.println("链表为空,无法删除");return;}HeroNode temp = head.next;boolean flag=false;//用于标记是否有得删除,有true,没有false//链表不为空的话进行遍历,然后找到要删除的前一个节点while (true) {//判断链表是否为最后一个了,如果是的话,就breakif (temp==null) {System.out.println("链表已经遍历完了,找不到,所以无法删除");flag=false;break;}if (temp.next.no==no) {//表示找到了,直接标记为找到flag=true;break;}//没有找到,就后移temp=temp.next;}if (flag==true) {temp.next=temp.next.next;}else {System.out.println("不存在要删除的链表节点");}}/*** 根据头部获取链表的有效值* @param head*/public int getLength(HeroNode head) {//判断链表是否为空,如果为空的话,就有效值就为0if (head.next==null) {return 0;}//链表不为空//标记一个值,来统计,每次可以遍历一个就加1。默认为0int size=0;HeroNode cur = head.next;while (cur != null) {size++;//后移cur=cur.next;}return size;}/*** 获取链表的倒数第几个节点* @param head 头结点* @param lastIndex 倒数第几个* @return 倒数第几个节点*/public HeroNode findLastIndexNode(HeroNode head, int lastIndex) {HeroNode temp = head.next;//链表为空,无法找if (temp==null) {System.out.println("链表为空,无法查找");return null;}//链表不为空int size=getLength(head);//链表的长度//查找的索引值不合理(小于0,获取大于链表的长度)if (lastIndex<=0||lastIndex>size) {System.out.println("查找的倒数索引不合理");return null;}HeroNode findNode=null;for (int i = 0; i < size-lastIndex; i++) {findNode=temp.next;temp=temp.next;}return findNode;}/*** 反向设置链表* @param head 传入要反向的头节点*/public void reverseSetList(HeroNode head) {//判断链表是否可以反向,或没必要反向:null,或者链表长度为1,那么没有必要反向if (head.next==null||head.next.next==null) {System.out.println("链表长度为null或者长度为1,没有必要反向");return;}//长度可以反向//用来反向的辅助头节点HeroNode reverseHead=new HeroNode(0,"","");//当前节点HeroNode cur = head.next;//当前节点的下一个节点,为了不断链HeroNode curNext = null;//遍历队列while (cur != null) {curNext=cur.next;//为当前节点的下一个节点赋值,目的是保证链表不断裂cur.next=reverseHead.next;//当前节点的下一个指向赋值头节点的下一个reverseHead.next=cur;//为辅助节点的下一个赋值cur=curNext;//当前节点后移}head.next=reverseHead.next;//最后头节点指向反向节点的next}}}

2.讲解

1.

2.

3.反思总结

1.curNext来保证链表不断。因为head的那个已经断了,所以后移要cur=curNext

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。