文章目录
单链表面试题
1.求单链表中有效节点的个数
// 方法 :获取到单链表的节点的个数(如果是带头节点的链表,需求不统计头节点)
* @param head 链表的头节点
* @return 返回有效节点的个数
1.1 代码实现
public static int getLength(HeroNode head) {
if (head.next == null) {//空链表
return 0;
}
int length = 0;
//定义一个辅助的变量,这里我们没有统计头节点
HeroNode cur = head.next;
while (cur != null) {
length ++;
cur = cur.next;//遍历
}
return length;
}
}
1.2 显示
在class SingleLinkedList中
//返回头节点
public HeroNode getHead() {
return head;
}
1.3 测试
求单链表中有效节点的个数
System.out.println("有效的节点个数"+getLength(singleLinkedList.getHead()));
2.查找单链表中倒数第K个节点【新浪面试题】
2.1 分析
2.2 代码实现
思路:
1.编写一个方法,接收head节点,同时接收一个index
2.index 表示是倒数第index个节点
3.先把链表从头到尾遍历,得到这个链表的总的长度getLength
4.得到size后,我们从链表的第一个开始白哪里(size–index)个,,就可以得到
5.如果找到了,则返回该节点,否则返回null
public static HeroNode findLastIndexNode(HeroNode 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;
}
//定义给辅助变量,for 循环定位到倒数的index
HeroNode cur = head.next;//3 //3-1 = 2
for (int i = 0; i < size - index; i++) {
cur = cur.next;
}
return cur;
}
2.3 测试
//测试一下看看是否得到了倒数的第K个节点
HeroNode res = findLastIndexNode(singleLinkedList.getHead(), 2);//倒数第二个
HeroNode res2 = findLastIndexNode(singleLinkedList.getHead(), 1);//倒数第一个
HeroNode res3 = findLastIndexNode(singleLinkedList.getHead(), 3);//倒数第三个
System.out.println(“res=”+res);//输出倒数第二行
System.out.println(“res=”+res2);//输出倒数第一行
System.out.println(“res=”+res3);//输出倒数第三行,没有,为空
2.4 输出
res=HeroNode [no=2, name=小路, nickname=小龙人]
res=HeroNode [no=3, name=吴用, nickname=豹子头]
res=null
3.单链表的反转【腾讯题面试】
3.1 分析
3.2 代码实现
//方法:将单链表反转【腾讯面试题】
//思路:
1.将原链表遍历到新的re链表,每一个替换都放在re的第一个位置
这样每一个进来的原链表的都占据在re的第一个位置,之前进re的被挤到后面去
从而re的序列就是原链表的反转
2.将re按顺序遍历到原链表,即可达成将单链表反转
public static void reversetList(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;//先暂时保存当前节点的下一个节点,因为后面需要使用
cur.next = reverseHead.next;//将cur的下一个节点指向新的链表的最前端
reverseHead.next = cur;//将cur连接到新的链表上 ,让节点与re的head相连接
cur = next;//让cur后移
}
//将head.next指向 reverseHead.next实现单链表的反转
head.next = reverseHead.next;
}
3.3 测试:
//测试单链表的反转功能
System.out.println("原链表:");
singleLinkedList.list();
//反转
System.out.println("反转单链表");
reversetList(singleLinkedList.getHead());
singleLinkedList.list();
3.4 输出:
原链表:
HeroNode [no=1, name=松江, nickname=及时雨]
HeroNode [no=2, name=卢俊义, nickname=玉麒麟]
HeroNode [no=3, name=吴用, nickname=豹子头]
反转单链表
HeroNode [no=3, name=吴用, nickname=豹子头]
HeroNode [no=2, name=卢俊义, nickname=玉麒麟]
HeroNode [no=1, name=松江, nickname=及时雨]
4.从头到尾打印单链表
4.1 分析
4.2 栈
4.3 栈的实例
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("smitch");
//出栈
//smitch,tom,jack
while (stack.size() > 0) {
System.out.println(stack.pop());//pop就是将栈顶的数据取出
}
}
}
4.4 代码实现
//方法:
利用栈数据结构,将各个节点压入到栈中,然后利用栈的先入后出的特点,实现逆序打印的效果
public static void reversePrint(HeroNode head) {
if (head.next == null) {
return;//空栈表,不能打印
}
//创建要给一个栈,将各个节点压入栈
Stack<HeroNode> stack = new Stack<HeroNode>();
HeroNode cur = head.next;
//将链表的所有节点压入栈中
while (cur != null) {
stack.push(cur);
cur = cur.next;//让cur后移,这样就可以压入下一个节点
}
//将栈中的节点进行打印,pop,出栈
while (stack.size() > 0) {
System.out.println(stack.pop());//stack的特点是先进后出
}
}
4.5 测试
System.out.println("逆序打印单链表,没有改变链表的结构");
reversePrint(singleLinkedList.getHead());
4.6 输出
原链表:
HeroNode [no=1, name=松江, nickname=及时雨]
HeroNode [no=2, name=卢俊义, nickname=玉麒麟]
HeroNode [no=3, name=吴用, nickname=豹子头]
逆序打印单链表,没有改变链表的结构
HeroNode [no=3, name=吴用, nickname=豹子头]
HeroNode [no=2, name=卢俊义, nickname=玉麒麟]
HeroNode [no=1, name=松江, nickname=及时雨]