单链表常见的几个面试题
- 新浪,腾讯内部面试题目
- 题目分析
- 代码实现
- 测试用例
一,面试题目
- 统计链表中有效节点的个数(不含头结点)【新浪】
- 获取链表中倒数第K个元素【新浪】
- 单向链表的逆转【腾讯】
二,题目分析
- 第一题:我们可以获取链表的头结点后,然后进行遍历,设置一个变量进行计数,注意不要算上头结点。
- 第二题:我们可以在第一题的基础上,在获取到了链表的长度后,只需要考虑倒数第K个节点是从前面开始第几个节点,我们就循环几次不就可以了?注意如果你的下标从0开始循环那就size - k就可以了,如果你是从1开始的那么就size-k+1就可以了。
- 第三题:我们需要创建一个新的头结点,然后把原来的那个节点从前往后依次放到新节点的后面,注意是newHeadNode.next始终等于新加入的那个元素;核心代码就是:oldNode.next = newHeadNode.next;newHeadNode.next = oldNode;就是这样移动,最后在把新的节点后的元素指向原来头结点:oldHeadNode = newHeadNode;
图解如下:
三,代码实现
第一题
//统计出有效的节点个数,不含头结点。
public static int getLength(HeroNode headHeroNode) {
int count = 0;
if (headHeroNode.next == null) {
return 0;
}
HeroNode temp = headHeroNode.next;//不统计头结点,有两种写法任选其一。
while (temp != null) {
count++;
temp = temp.next;
}
return count;
}
第二题
//查找单链表中的倒数第k个结点【新浪面试题】
public static void find(HeroNode head,int index){
if (head.next == null) {
System.out.println("英雄榜为空!");
return ;
}
HeroNode temp = head;
int size = getLength(head);
if (index >size||index<0) {
System.out.println("输入的K不合法!");
}else {
for (int i = 1; i <= size-index+1; i++) {
temp = temp.next;
}
System.out.println("倒数第K个元素是:"+temp);
}
}
第三题:
//链表逆转【腾讯面试题目】
public static void reverse(HeroNode head) {
if (head.next == null || head.next.next ==null) {
System.out.println("链表未发生变化!");
return;
}
HeroNode current = head.next;
HeroNode newheadHeroNode =new HeroNode(0,"","");
HeroNode currentnext = null;
while (current != null) {
currentnext = current.next;
current.next = newheadHeroNode.next;
newheadHeroNode.next = current;
current = currentnext;
}
head.next = newheadHeroNode.next;
System.out.println("链表已经逆转");
}
完整的测试代码如下:
package com.atxiaopeng.linkedlist;
import java.util.Scanner;
public class SingleLinkedListDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 1,创建英雄榜
SingleLinkedlist s = new SingleLinkedlist();
// HeroNode h1 = new HeroNode(1, "阿珂", "节奏热浪");
// HeroNode h2 = new HeroNode(2, "猴子", "大圣娶亲");
// HeroNode h3 = new HeroNode(3, "李白", "凤 求 凰");
// HeroNode h4 = new HeroNode(4, "露娜", "紫霞仙子");
boolean b = true;
while (b) {
System.out.println("==========王者英雄榜==========");
System.out.println(" 1,创建英雄并进榜(无序) ");
System.out.println(" 2,创建英雄并进榜(有序)");
System.out.println(" 3,修改英雄属性 ");
System.out.println(" 4,英雄榜删除英雄 ");
System.out.println(" 5,显示当前英雄榜 ");
System.out.println(" 6,英雄总榜人数 ");
System.out.println(" 7,查找倒数第K个英雄 ");
System.out.println(" 8,英雄逆序排列 ");
System.out.println(" 9,退出程序 ");
System.out.println("===========================");
System.out.print("输入操作的选项: ");
int key = new Scanner(System.in).nextInt();
switch (key) {
case 1:
s.createHero1();
break;
case 2:
s.createHero2();
break;
case 3:
s.update();
break;
case 4:
s.delete();
break;
case 5:
s.show();
break;
case 6:
System.out.println(getLength(s.getHeadHeroNode()));
break;
case 7:
find(s.getHeadHeroNode(), 1);
break;
case 8:
reverse(s.getHeadHeroNode());
break;
case 9:
b = false;
System.out.println("程序成功退出!");
break;
default:
break;
}
}
}
//统计出有效的节点个数,不含头结点。
public static int getLength(HeroNode headHeroNode) {
int count = 0;
if (headHeroNode.next == null) {
return 0;
}
HeroNode temp = headHeroNode.next;//不统计头结点,有两种写法任选其一。
while (temp != null) {
count++;
temp = temp.next;
}
return count;
}
//查找单链表中的倒数第k个结点【新浪面试题】
public static void find(HeroNode head,int index){
if (head.next == null) {
System.out.println("英雄榜为空!");
return ;
}
HeroNode temp = head;
int size = getLength(head);
if (index >size||index<0) {
System.out.println("输入的K不合法!");
}else {
for (int i = 1; i <= size-index+1; i++) {
temp = temp.next;
}
System.out.println("倒数第K个元素是:"+temp);
}
}
//链表逆转【腾讯面试题目】
public static void reverse(HeroNode head) {
if (head.next == null || head.next.next ==null) {
System.out.println("链表未发生变化!");
return;
}
HeroNode current = head.next;
HeroNode newheadHeroNode =new HeroNode(0,"","");
HeroNode currentnext = null;
while (current != null) {
currentnext = current.next;
current.next = newheadHeroNode.next;
newheadHeroNode.next = current;
current = currentnext;
}
head.next = newheadHeroNode.next;
System.out.println("链表已经逆转");
}
}
class SingleLinkedlist {
// 1,创建头结点,不存放数据,不让随便动
private HeroNode headHeroNode = new HeroNode(0, "", "");
public HeroNode getHeadHeroNode() {
return headHeroNode;
}
boolean flag = false;// 判断标志,例如:判断为空的标志等
// 创建英雄并无序插入
public void createHero1() {
System.out.print("输入你要加入英雄的排名:");
int newNu = new Scanner(System.in).nextInt();
System.out.print("输入你要加入英雄的名字:");
String newName = new Scanner(System.in).next();
System.out.print("输入你要加入的英雄的常用皮肤:");
String newSkin = new Scanner(System.in).next();
add(new HeroNode(newNu, newName, newSkin));
}
// 创建英雄并有序插入
public void createHero2() {
System.out.print("输入你要加入英雄的排名:");
int newNu = new Scanner(System.in).nextInt();
System.out.print("输入你要加入英雄的名字:");
String newName = new Scanner(System.in).next();
System.out.print("输入你要加入的英雄的常用皮肤:");
String newSkin = new Scanner(System.in).next();
addByordering(new HeroNode(newNu, newName, newSkin));
}
// 2,无序插入
public void add(HeroNode heroNode) {
HeroNode temp = headHeroNode;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.nu == heroNode.nu) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("排名 : " + heroNode.nu + " 英雄之前已经加入,不能再次加入!");
} else {
heroNode.next = temp.next;
temp.next = heroNode;
System.out.println(heroNode.name + " 成功加入王者英雄榜!(无序)");
}
flag = false;
}
// 3,有序插入
public void addByordering(HeroNode heroNode) {
HeroNode temp = headHeroNode;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.nu > heroNode.nu) {
break;
} else if (temp.next.nu == heroNode.nu) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("排名 : " + heroNode.nu + " 英雄之前已经加入,不能再次加入!");
} else {
heroNode.next = temp.next;
temp.next = heroNode;
System.out.println(heroNode.name + " 成功加入王者英雄榜!(有序)");
}
flag = false;
}
// 删除英雄
public void delete() {
HeroNode temp = headHeroNode;
HeroNode random;
if (temp.next == null) {
System.out.println("英雄榜为空,无法删除!!!");
return; // 直接返回,不再继续往下运行
}
System.out.print("输入要删除英雄的名字:");
Scanner input = new Scanner(System.in);
String s1 = input.next();
while (true) {
if (temp.next == null) {
flag = true;
break;
} else if (temp.next.name.equals(s1)) {
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("英雄榜中不存在该英雄,无法删除!!!");
} else {
random = temp.next;
temp.next = random.next;
System.out.println(random.name + " 英雄删除成功!");
}
flag = false;
}
// 修改英雄属性
public void update() {
HeroNode temp = headHeroNode;
if (temp.next == null) {
System.out.println("英雄榜为空,无法修改!");
return;
}
System.out.print("输入你要修改的英雄的名字:");
String name = new Scanner(System.in).next();
while (true) {
if (temp.next == null) {
flag = true;
break;
} else if (temp.next.name.equals(name)) {
break;
}
temp = temp.next;
}
if (flag) {
System.out.println("英雄榜中不存在该英雄,无法修改!!!");
} else {
System.out.print("输入你要修改英雄的名字:");
String newName = new Scanner(System.in).next();
System.out.print("输入你要修改的英雄的常用皮肤:");
String newSkin = new Scanner(System.in).next();
temp.next.name = newName;
temp.next.skin = newSkin;
System.out.println("===英雄榜已更新!===");
}
flag = false;
}
// 显示英雄榜
public void show() {
HeroNode temp = headHeroNode;
if (temp.next == null) {
System.out.println("王者英雄榜尚未有英雄加入!");
return;
}
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
System.out.println(temp + " ");
}
}
}
class HeroNode {
public int nu;
public String name;
public String skin;
public HeroNode next;
public HeroNode(int n, String name, String skin) {
this.nu = n;
this.name = name;
this.skin = skin;
}
@Override
public String toString() {
return "王者英雄榜 :[排名=" + nu + ", 名字=" + name + ", 皮肤=" + skin + "]";
}
}
欢迎指正,共同学习!
来源:CSDN
作者:@大美妞
链接:https://blog.csdn.net/qq_39586922/article/details/104820454