单链表几道面试题

1、对单链表进行逆置
 /*
    * 单链表的反转,利用头插法的思想
    * */
    public void reveList(Hero_Node head)
    {
        /*
        * 当单链表当中没有节点或者说只有一个节点的时候就不用逆序了,直接返回
        * */
        if(head.Next_hero==null||head.Next_hero.Next_hero==null)
        {
            return;
        }
        /*
        * 定义一个辅助节点用于遍历原先没有逆置的节点
        * */
        Hero_Node temp = head.Next_hero;

        /*
        * 定义一个节点用于指向当前节点的下一个节点
        * */
        Hero_Node next = null;
        /*
        * new一个新的链表的头节点
        * */
        Hero_Node reveHeadNode = new Hero_Node(0,null,null);
        while (temp!=null)
        {
            /*
            * 先保留当前节点的下一节点
            * */
            next=temp.Next_hero;
            /*
            * 让每个新添加进来的节点都添加在reveHeadNode后面,这样就实现了头插的效果,reveHeadNode的位置保持不变
            * */
            /*
            * 先让temp指向reveHeadNode的下一个节点
            * */
            temp.Next_hero=reveHeadNode.Next_hero;
            /*
            * 然后让reveHeadNode指向新插入进来的这个节点
            * */
           reveHeadNode.Next_hero=temp;
           temp=next;//让temp后移至前面保留的下一个节点
        }
        /**
        最后还需要让原先的头节点只想现在的第一个有效节点
        */
        head.Next_hero = reveHeadNode.Next_hero;
    }
2、逆序打印一个单链表
/*
* 逆序打印一个单链表
* 1、方式一:采用上述的逆转单链表的方式,先将单链表逆置然后再打印,但是这种方式存在问题是,会将原先的单链表结构进行破坏
* 2、利用栈的思想,将原先的单链表中的节点压入栈中,然后再将栈中元素弹出即可
* */
public static void revePrint(Hero_Node head)
{
    Stack<Hero_Node> stack = new Stack<>();
    Hero_Node temp = head;
    /*
    * 1、先判断单链表是否为空
    * */
    if (temp.Next_hero==null)
    {
        return;
    }
    while (temp.Next_hero!=null)
    {

            /*
            * 将单链表的节点压栈
            * */
            stack.push(temp.Next_hero);
            temp=temp.Next_hero;
    }
    /*
    * 如果栈中有元素就将栈顶的元素打印出来
    * */
    while (stack.size()>0)
    {
        System.out.println(stack.pop());
    }

}
3、合并两个有序的单链表合并之后还是有序的
/*
* 合并两个有序的链表,合并之后让他们还是有序的
* */
public static void Merge_Single_List(Hero_Node head1,Hero_Node head2)
{
    /*
    * 对两个链表分别创建一个工具节点进行后移操作
    * */
    Hero_Node temp1 = head1.Next_hero;
    Hero_Node temp2 = head2.Next_hero;
    /*
    * 为两个节点分别创建一个next节点用于保存当前结点的下一节点
    * */
    Hero_Node next1=null;
    Hero_Node next2=null;
    /*
    * 为新链表创建一个头结点
    * */
    Hero_Node newHead = new Hero_Node(0,null,null);
    /*
    * 因为两个链表合并可能存在一个遍历完一个还没遍历完的情况,一个不为空或者另外一个不为空,这样在后面的代码当中要考虑好空指针问题
    * */
    while (temp1!=null||temp2!=null)
    {
        /*
        * 先保留当前节点的下一节点
        * */

        /*
        * 解此题一定要注重空指针异常,因为两个链表在按照顺序合并的过程中,随时可能出现一个链表遍历完但是另外一个链表还没完,所以要考虑好每种情况
        * 1、当两个链表都不为空的时候
        * 2、当其中一个链表已经为空时
        * 3、这些情况都要考虑周全,不然随时都有可能出现空指针异常
        * */


        /*
        * 1、当temp不为空的时候再让next执行去指向下一个节点,如果你不区分有可能有可能此时temp已经为空你还让他指向下一个,你让她拿什么给你指
        * */
        if(temp1!=null)
        {
            next1=temp1.Next_hero;
        }
        if(temp2!=null)
        {
            next2=temp2.Next_hero;
        }

        /*
        * 2、两个都还没有走完的情况
        * */
        if(temp1!=null&&temp2!=null)
        {
            if(temp1.getNo()<temp2.getNo())
            {
                temp1.Next_hero=newHead.Next_hero;
                newHead.Next_hero=temp1;
                temp1=next1;
            }
            else
            {
                temp2.Next_hero=newHead.Next_hero;
                newHead.Next_hero=temp2;
                temp2=next2;
            }
        }
        /*
        * temp1空,temp2没空
        * */
        if(temp1==null&&temp2!=null)
        {
            temp2.Next_hero=newHead.Next_hero;
            newHead.Next_hero=temp2;
            temp2=next2;
        }
        /*
        * temp2空,temp1没空
        * */
        if(temp2==null&&temp1!=null)
        {
            temp1.Next_hero=newHead.Next_hero;
            newHead.Next_hero=temp1;
            temp1=next1;
        }
    }
    /*
    * 最后让原先的头节点指向现在头节点的下一个节点
    * */
    head1.Next_hero=newHead.Next_hero;
    head2.Next_hero=newHead.Next_hero;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值