学习Java数据结构与算法的第四天

新浪、百度、腾讯的单链表面试题

单链表常见的面试题如下:

  1. 求单链表中有效结点的个数
  2. 查找单链表中的倒数第k个结点【新浪面试题】
  3. 单链表的反转【腾讯面试题】
  4. 从尾到头打印单链表【百度,要求方式1:反向遍历。方式2:Stack栈】
  5. 合并两个有序的单链表,合并之后的链表依然有序

第一题

思路分析:
直接定义一个辅助变量来遍历单链表并且记录单链表长度,注意带头结点的单链表应该去掉头结点

代码实现如下:

// 获取单链表有效结点的个数(如果是带头结点的链表,需要将头结点去掉)
	/*
	 * head是链表的头结点 返回的是单链表中有效结点的个数
	 */
	public static int getLength(HeroNode head) {
		if (head.next == null) { //单链表为空,返回0
			return 0;
		}
		int length = 0;
		// 定义一个辅助的变量,这里没有统计头结点
		HeroNode cur = head.next;
		while (cur != null) {
			length++;
			cur = cur.next;
		}
		return length;
	}

测试代码如下:

// 测试单链表有效结点的个数
	System.out.println("有效的节点个数=" + getLength(singleLinkedList.getHead()));

第二题

思路分析:

  • 首先在管理单链表的类中编写一个方法用来接收head结点,同时接收一个index
  • index表示的是倒数第index个结点
  • 先把链表从头到尾遍历一下,得到链表的总长度getLength
  • 得到size后,我们从链表的第一个开始遍历(size-index)个,便得到倒数第index个结点

代码实现如下:

public HeroNode getHead() {
	return head;
}

public static HeroNode findLastIndexNode(HeroNode head, int index) {
	if(head.next == null){
		return null; //单链表为空
	}
	int size = getLength(head);
	//第二次遍历找到size-index位置,就是我们倒数的第k个结点
	//先做一个index的校验
	if(index <= 0 || index > size) {
		return null;
	}
	//定义一个辅助变量,用for循环定位到倒数的index
	HeroNode cur = head.next;
	for(int i=0; i<size-index; i++) {
		cur = cur.next;
	}
	return cur;
}

测试代码如下:

//测试一下看看是否得到了倒数第k个结点
	HeroNode res = findLastIndexNode(singleLinkedList.getHead(),1);
	System.out.println("res=" + res);

第三题

思路分析:

  • 先定义一个结点reverseHead = new HeroNode();
  • 从头到尾遍历原来的链表,每遍历一个结点,就将其取出,并放在新的链表的最前端
  • 原来的链表的head.next = reverseHead.next【头插法】

代码实现如下:

//将单链表进行反转
	public static void reverseList(HeroNode head) {
		//如果当前链表为空,或者只有一个结点,则无需反转直接返回
		if(head.next == null || head.next.next == null) {
			return;
		}
		//定义一个辅助的指针变量,帮助我们遍历原来的链表
		HeroNode cur = head.next;
		HeroNode next = null; //指向当前结【cur】点的下一个结点
		HeroNode reverseHead = new HeroNode(0,"","");
		//遍历原来的链表,每遍历一个结点,就将其取出,并放在新的链表reverseHead的最前端
		while(cur != null) {
			next = cur.next; //将next指向cur.next,先暂时保存当前结点的下一个结点,因为后面需要使用
			cur.next= reverseHead.next; //将cur的下一个结点指向新的链表的最前端
			reverseHead.next = cur;
			cur = next; //让cur指向next
		}
		//将head.next指向reverseHead.next,实现单链表的反转
		head.next = reverseHead.next;
	}

测试代码如下:

// 创建一个链表
		SingleLinkedList singleLinkedList = new SingleLinkedList();
		// 加入
		singleLinkedList.add(hero1); 
		singleLinkedList.add(hero2);
		singleLinkedList.add(hero3); 
		singleLinkedList.add(hero4);
		 

		//测试单链表反转
		System.out.println("原来链表的情况");
		singleLinkedList.list();
		System.out.println("反转单链表");
		reverseList(singleLinkedList.getHead());
		singleLinkedList.list();

第四题

思路分析:

  • 要求逆序打印单链表
  • 方式1:先将单链表进行反转操作,然后进行遍历即可(问题:会破坏原来的单链表的一个结构)
  • 方式2:可以利用栈这个数据结构,将各个结点压入栈中,然后利用栈的先进后出的特性,就实现了逆序打印的效果

栈的代码实现:

package com.linklist;

import java.util.Stack;

//用来演示栈Stack的基本使用
public class TestStack {

	public static void main(String[] args) {
		Stack<String> stack = new Stack();
		//入栈
		stack.add("jack");
		stack.add("tom");
		stack.add("smith");
		//出栈
		//smith,tom,jack
		while(stack.size() > 0) {
			System.out.println(stack.pop());//将栈顶的数据取出
		}
	}
}

第四题代码实现如下:

//使用栈的方式逆序打印单链表中的数据
	public static 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; //让cur后移
		}
		//将栈中的结点进行打印,pop出栈
		while(stack.size() > 0) {
			System.out.println(stack.pop()); //先进后出
		}
	}

测试代码如下:

//测试逆序打印单链表
		System.out.println("原来的链表结构");
		singleLinkedList.list();
		System.out.println("测试逆序打印单链表,没有改变链表本身的结构");
		reversePrint(singleLinkedList.getHead());

第五题

思路分析:
定义一个新的链表,遍历并比较原来两个链表中编号最小的结点,并将最小的结点添加到新的链表中

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值