数据结构(Java实现)-单链表常见面试题(新浪、百度、腾讯)

1、求单链表中有效节点个数

思路:遍历链表获取单链表的节点的个数(如果是带头节点的链表,不能统计头节点)

public static int getLength(LinkNode head)
{
    if(head.next==null)
    {
        return 0;//空链表
    }
    int length=0;
    //定义一个辅助的变量,这里我们没有统计头节点
    LinkNode cur = head.next;
    while(cur != null)
    {
        length++;
        cur = cur.next;//继续向下遍历
    }
    return length;
}

2、查找单链表中的倒数第k个节点(新浪面试题)

思路:

  1. 编写一个方法,接收head节点,同时接收一个index值(即k的值)
  2. 先把链表从头到尾遍历,得到链表的总长度 ,用上一题的getLength()方法
  3. 得到长度size后,我们从链表的第一个开始遍历(size-index)个,就可以得到
  4. 如果找到了,返回该节点,否则返回null
public static LinkNode findLastIndexNode(LinkNode head,int index)
{
	//判断如果链表为空,返回null
	if(head.next == null)
	{
		return null;
	}
	//第一遍遍历得到长度
	int size = getLength(head);
	//第二次遍历size-index位置,就是倒数的第K个节点
	//先做一个index校验
	if(index <= 0 || index > size)
	{
		return null;
	}
	//定义一个辅助变量cur,for循环定位到倒数的index
	LinkNode cur = head.next;
	for(int i=0;i<size-index;i++)
	{
		cur = cur.next;//向后遍历
	}
	return cur;
}

3、单链表的反转(腾讯面试题)

思路:

  1. 先定义一个新的头节点reverseHead = new LinkNode();
  2. 从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表头reverseHead.next上
  3. 原来的链表头head.next = reverseHead.next
public static void reversetList(LinkNode head)
{
	//如果当前链表为空,或者只有一个节点,无需反转,直接返回
	if(head.next == null || head.next.next == null)
	{
		return;
	}
	//定义一个辅助变量,帮助我们遍历原来的链表
	LinkNode cur = head.next;
	StudentLinkNode temp = null;//定义一个空的temp节点
	LinkNode reverseHead = new LinkNode();
	//遍历原来的链表,每遍历一个节点,就将其取出并放在新的reverseHead的后面第一个节点的位置
	while(cur != null)
	{
		temp = cur.next;//空的temp节点暂时储存当前节点cur的下一个节点
		cur.next = reverseHead.next;//将cur的下一个节点指向新的链表的最前端
		reverseHead.next = cur;//将cur连接到新的链表上
		cur = cur.next;
	}
	//将head.next指向reverseHead,next实现单链表的反转
	head.next = reverseHead.next;

}

4、从尾到头打印单链表

思路:

  1. 这道题目要求的是逆序打印单链表
  2. 方式一:先将单链表进行反转操作,然后进行遍历即可,但是这样做的问题是会破坏原来的单链表的结构(不建议)
  3. 方式二:可以利用这个数据结构,将各个节点压入到栈中,然后利用栈的先进后出的特点,就实现了逆序打印的效果。
public static void reversePrint(LinkNode head)
{
	if(head.next == null)
	{
		return;//空链表,不能打印
	}
	//创建一个栈,将各个节点压入栈中
	Stack<LinkNode> Stack = new Stack<LinkNode>();
	LinkNode cur = head.next;
	//将链表的所有节点压入栈中
	while(cur != null)
	{
		stack.push(cur);
		cur = cur.next;//cur后移,这样就可以压入下一个节点
	}
	//将栈中的节点进行打印,pop出栈
	while(stack.size()>0)
	{
		System,out.println(stack.pop());//stack的特点就是先进的后出
	}
}

5、合并两个有序的单链表,合并之后的链表依然有序

思路:

  1. cur1 和cur2 分别是两条有序链表的辅助引用(指针)方便两个链表的遍历,result 则为合并之后的结果链表,tail为结果链表的最后一个节点,方便尾插
  2. cur1 和 cur2 同时往后走,两个引用所指的数分别比较,拿出来的节点尾插在result链表中

public static LinkNode mergeList(LinkNode node1,LinkNode node2)
{
	//定义一个辅助变量cur1,帮助我们遍历第一条链表
    LinkNode cur1 = node1;
	//定义一个辅助变量cur2,帮助我们遍历第二条链表
    LinkNode cur2 = node2;
    LinkNode result = new LinkNode();//定义节点temp为合并后产生的新链表的头节点
	//result 则为合并之后的结果链表头节点,tail为结果链表的最后一个节点,方便尾插
    result = null;
    ListNode tail = null;
	//定义一个空的temp节点
    ListNode next = null;
    while((cur1 != null)  &&  (cur2 != null))
	{
		if(cur1.data <= cur2.data)
		{
			if(result != null)//当结果链表不为空时
			{   
				temp = cur1.next;  // temp节点保存链表1的下一个节点,让循环可以继续
                tail.next = cur1;   // 插入过程
                cur1.next = null;
                tail = cur1;  //保存结果链表的最后一个节点
                cur1 = temp;
            }
			else
			{   // 结果链表为空时
                temp = cur1.next;
                result = cur1;
                cur1.next = null;
                //保存新的最后一个节点
                tail = cur1;
                cur1 = temp;
            }
        }
		else
		{
            if(result != null)
			{
                temp = cur2.next;
                tail.next = cur2;
                cur2.next = null;
                tail = cur2;
                cur2 = temp;
            }
			else
			{
                temp = cur2.next;
                result = cur2;
                cur2.next = null;
                //保存新的最后一个节点
                tail = cur2;
                cur2 = temp;
            }
        }
    }
    //其中一个链表为空之后
    //第一条链表的cur1走完以后,第二条链表的cur2还没走完就直接插到结果链表的尾部
    if(cur1 == null)
	{
        tail.next = cur2;
    }
    //第二条链表的cur2走完以后,第一条链表的cur1还没走完就直接插到结果链表的尾部
    if(cur2 == null){
        tail.next = cur1;
    }
	return result;
}

猜你喜欢

转载自blog.csdn.net/weixin_44279178/article/details/108007204
今日推荐