004 | 线性表面试经典上
程序员文章站
2022-06-09 15:54:30
...
写在前面:纸上得来终觉浅,绝知此事要躬行!有人说学数据结构光看不练就是耍牛氓,通过这几天的练习,感觉看跟写真的是两码事,前者是面儿后者才是里。
-
若某表最常用的操作是在最后一个结点之后插入一个节点或删除最后一二个结点,则采用()省运算时间。
A. 单链表
B. 双链表
C. 单循环链表
D. 带头结点的双循环链表
答案:D
解析:单链表和双链表每次找到尾部都需要遍历整个链表,单循环链表是单向的,找到尾部也需要遍历整个链表! -
构造线性表结点类,下面后续的练习都采用此类:
package link;
/**
* User: ZhangQi
* Date: 2019/3/8
* Time: 9:52
* Desc: 结点类
*/
public class ListNode {
//数值域
int val;
//指针域
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
- 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
package link;
import java.util.ArrayList;
/**
* User: ZhangQi
* Date: 2019/3/8
* Time: 9:57
* Desc: 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
*/
public class Solution {
/**
* 思路一:由于需要倒叙输出链表,所以第一时间想到的是反转链表然后在遍历取值
*/
ArrayList<Integer> list = new ArrayList<>();
public ArrayList<Integer> printListFromTailToHead1(ListNode listNode) {
if(listNode == null) return list;
ListNode next = null;
ListNode pre = null;
/** 反转链表 */
while(listNode!=null){
next = listNode.next;
listNode.next = pre;
pre = listNode;
listNode = next;
}
/** 遍历反转后的链表取值 */
while(pre!=null){
list.add(pre.val);
pre = pre.next;
}
return list;
}
/**
* 思路2:由于单链表只能从前往后遍历,而需要是需要倒叙链表,也就是先进后出的场景,
* 而从想到 栈结构 进而想到递归
* @param listNode
* @return
*/
public ArrayList<Integer> printListFromTailToHead2(ListNode listNode) {
if(listNode == null) return list;
/** 使用递归必须要有一个退出条件 */
if (listNode != null) {
this.printListFromTailToHead2(listNode.next);
list.add(listNode.val);
}
return list;
}
}
- 输入一个链表,输出该链表中倒数第k个结点
package link;
/**
* User: ZhangQi
* Date: 2019/3/8
* Time: 9:57
* Desc: 输入一个链表,输出该链表中倒数第k个结点
*/
public class Solution {
/**
* 思路:定义快指针和慢指针,当快指针走到 k-1 步的时候,快,慢指针一起走,
* 当快指针遍历完链表的时候,慢指针所在到结点就是倒数第k个结点率
* @param head
* @param k
* @return
*/
public ListNode FindKthToTail(ListNode head, int k) {
if (head == null || k <= 0) return null;
/** 初始化快,慢指针,使其指向头指针 */
ListNode fast = head;
ListNode show = head;
/** 快指针先走,让其到达 k-1 结点处 */
while (fast != null && k > 0) {
fast = fast.next;
k--;
}
/** 快慢一起走,直至快指针遍历完链表 */
while (fast != null) {
show = show.next;
fast = fast.next;
}
/** 判断 k 值是否大于链表长度 */
return k > 0 ? null : show;
}
}
- 输入一个链表,反转链表后,输出新链表的表头
package link;
/**
* User: ZhangQi
* Date: 2019/3/8
* Time: 9:57
* Desc: 输入一个链表,反转链表后,输出新链表的表头
*/
public class Solution {
/**
* 思路:反转链表主要是对指针域进行转向操作
* @param head
* @return
*/
public ListNode ReverseList(ListNode head) {
ListNode newLink = null;
ListNode next = null;
while (head != null) {
/** 记录下一个结点位置,避免遗失 */
next = head.next;
/** 反转指针域使其指向上一个结点 */
head.next = newLink;
/** 新链表向前进一步,这一步一定要在下一步之前完成 */
newLink = head;
/** 最后旧链表指针向前一步进行遍历 */
head = next;
}
return newLink;
}
}
上一篇: Math.round(11.5)
推荐阅读
-
eclipse中部署在tomcat上的项目能正常运行,但无法访问tomcat默认首页
-
关于7206VXR路由器上如何防范BT
-
Spring Boot面试题(2020最新版)
-
经典_用js快速实现鼠标和键盘选择下拉菜单(代码详解)
-
线性表的链式存储结构:定义、单链表存储结构、给链表头结点分配空间、初始化链表数据、输出链表、在某个位置上插入数据、头插法、尾插法、删除某个位置上的数据、删除某个数据、删除整个链表计算链表的长度
-
hadoop入门:在windows上用Eclipse编写程序
-
我想用php读取网页上的一些数值
-
记一次.NET代码重构(上)
-
求PHP 上什么控件或函数可以发起XML请求和获取回数据解决办法
-
网站加载速度过慢,主若是图片上加载过慢