1Java学习笔记之数据结构——单链表
2017-03-26 10:54
435 查看
前两天找工作面试过程中,被一家搞大数据的问到了二叉树、算法相关的,本来大学时就没学好,经过几年的工作,平时用的更少,一下子看着题简单,就是写不上来。
因为工作中总是一上来不管什么类型,就开始Array,ArrayList,HashMap,HashSet就搞起了,好像就没用过什么的别的结构。虽然明知道这样是不对的,但是那种懒劲上来,别的都不管了。最近危机感非常重,因为慢慢发现虽然会的框架越来越多,配的越来越溜,数据库表设计也越来越规范,但是总感觉根基不稳。这种不稳的感觉来自于对框架底层的实现的漠视和数据结构的生疏。
数据结构学不好,则会导致在编码中一些场合选型错误,性能低下,内存大。框架吃不透,设计模式不精,则会导致系统模块间耦合性高,难以修改,做不了大项目。
所以决定重拾一下之前落下的知识,从0再学一遍。找了本书,就按书的目录来一篇一篇学习,记录。供日后自己随时查看。
第一篇是单链表。
单链表是个很简单,概念很容易理解的数据结构。就是每个节点只需要记录自己的值,和下一个节点的地址。好比幼儿园排队一样,老师说,每个同学你只需要记住你后面的同学是谁就可以了。这样这个队就能排起来了,每次小朋友只需要找到自己后面的人,让他站自己后面就可以了。
特点就是每次要找某个节点,都需要从头开始遍历,查询效率低,不如数组和ArrayList能记录节点的下标位置,根据下标位置直接就能找到。但是插入和删除时效率高,因为只需要在被插入的位置移动一个节点就可以了,而ArrayList则需要移动所有的在被插入位置的后面元素,会整体往后推一个位置。
下面来实现一个简单的单链表模型。
定义一个节点类Node,一个属性String用来存值,一个Node对象用来存下个节点。
再定义一个LinkedList来代表这个单链表结构,里面有添加到末尾,添加到某个位置等方法
package singlelink;
/**
* Created by wuwf on 2017/3/25.
* 单链表
*/
public class LinkedList {
private int size;
/*
* 头节点
*/
private Node head;
public LinkedList() {
size = 0;
}
public int size() {
return size;
}
public void print() {
if (size == 0) {
System.out.println("空列表");
return;
}
Node node = head;
while (node != null) {
System.out.println(node.getData());
node = node.getNext();
}
}
/**
* 在末尾追加一个节点
*
* @param node
*/
public void add(Node node) {
if (node == null) {
return;
}
//如果链表为空,那新增的这个node就作为head
if (size == 0) {
head = node;
} else { //添加到末尾
Node last = head;
while (last.getNext() != null) {
last = last.getNext();
}
last.setNext(node);
}
size++;
}
/**
* 在某个位置插入一个节点
*
* @param index
* @param node
*/
public void insert(int index, Node node) {
if (index < 0 || index > size) {
throw new RuntimeException("越界");
}
if (node == null) {
return;
}
//插头部
if (index == 0) {
node.setNext(head);
head = node;
} else {
Node tempNode = head;
for (int i = 0; i < index - 1; i++) {
//取到要被插入的节点的父节点
tempNode = tempNode.getNext();
}
node.setNext(tempNode.getNext());
tempNode.setNext(node);
}
size++;
}
}
LinkedList里定义了一个属性size来记录链表的总长度,里面不能存在null的值。
head代表第一个节点,如果head也为null,代表该链表为空的。
add方法是在末尾追加一个节点,这个比较好理解。做法就是从head到尾遍历,然后在尾节点setNext(新节点)即可。
insert方法解释一下,是在某个位置插入一个节点。做法是先找到要被插入的位置的上一个节点(父节点A),然后将新节点B作为A的next节点,再将原来的A的next作为新节点B的next即可。理解很容易,写成代码时还需要做一些越界和为空判断。
我只写了add和insert,只要这两个理解了,那么delete其实和add是一样的步骤。
因为工作中总是一上来不管什么类型,就开始Array,ArrayList,HashMap,HashSet就搞起了,好像就没用过什么的别的结构。虽然明知道这样是不对的,但是那种懒劲上来,别的都不管了。最近危机感非常重,因为慢慢发现虽然会的框架越来越多,配的越来越溜,数据库表设计也越来越规范,但是总感觉根基不稳。这种不稳的感觉来自于对框架底层的实现的漠视和数据结构的生疏。
数据结构学不好,则会导致在编码中一些场合选型错误,性能低下,内存大。框架吃不透,设计模式不精,则会导致系统模块间耦合性高,难以修改,做不了大项目。
所以决定重拾一下之前落下的知识,从0再学一遍。找了本书,就按书的目录来一篇一篇学习,记录。供日后自己随时查看。
第一篇是单链表。
单链表是个很简单,概念很容易理解的数据结构。就是每个节点只需要记录自己的值,和下一个节点的地址。好比幼儿园排队一样,老师说,每个同学你只需要记住你后面的同学是谁就可以了。这样这个队就能排起来了,每次小朋友只需要找到自己后面的人,让他站自己后面就可以了。
特点就是每次要找某个节点,都需要从头开始遍历,查询效率低,不如数组和ArrayList能记录节点的下标位置,根据下标位置直接就能找到。但是插入和删除时效率高,因为只需要在被插入的位置移动一个节点就可以了,而ArrayList则需要移动所有的在被插入位置的后面元素,会整体往后推一个位置。
下面来实现一个简单的单链表模型。
定义一个节点类Node,一个属性String用来存值,一个Node对象用来存下个节点。
package singlelink; /** * Created by wuwf on 2017/3/25. */ public class Node { private String data; private Node next; public Node(String data) { this.data = data; next = null; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } }
再定义一个LinkedList来代表这个单链表结构,里面有添加到末尾,添加到某个位置等方法
package singlelink;
/**
* Created by wuwf on 2017/3/25.
* 单链表
*/
public class LinkedList {
private int size;
/*
* 头节点
*/
private Node head;
public LinkedList() {
size = 0;
}
public int size() {
return size;
}
public void print() {
if (size == 0) {
System.out.println("空列表");
return;
}
Node node = head;
while (node != null) {
System.out.println(node.getData());
node = node.getNext();
}
}
/**
* 在末尾追加一个节点
*
* @param node
*/
public void add(Node node) {
if (node == null) {
return;
}
//如果链表为空,那新增的这个node就作为head
if (size == 0) {
head = node;
} else { //添加到末尾
Node last = head;
while (last.getNext() != null) {
last = last.getNext();
}
last.setNext(node);
}
size++;
}
/**
* 在某个位置插入一个节点
*
* @param index
* @param node
*/
public void insert(int index, Node node) {
if (index < 0 || index > size) {
throw new RuntimeException("越界");
}
if (node == null) {
return;
}
//插头部
if (index == 0) {
node.setNext(head);
head = node;
} else {
Node tempNode = head;
for (int i = 0; i < index - 1; i++) {
//取到要被插入的节点的父节点
tempNode = tempNode.getNext();
}
node.setNext(tempNode.getNext());
tempNode.setNext(node);
}
size++;
}
}
LinkedList里定义了一个属性size来记录链表的总长度,里面不能存在null的值。
head代表第一个节点,如果head也为null,代表该链表为空的。
add方法是在末尾追加一个节点,这个比较好理解。做法就是从head到尾遍历,然后在尾节点setNext(新节点)即可。
insert方法解释一下,是在某个位置插入一个节点。做法是先找到要被插入的位置的上一个节点(父节点A),然后将新节点B作为A的next节点,再将原来的A的next作为新节点B的next即可。理解很容易,写成代码时还需要做一些越界和为空判断。
我只写了add和insert,只要这两个理解了,那么delete其实和add是一样的步骤。
相关文章推荐
- 2Java学习笔记之数据结构——双向链表
- 7Java学习笔记之数据结构——HashMap
- 3Java学习笔记之数据结构——栈
- JAVA 数据结构与算法学习笔记一(转载)
- Java之数据结构基础、线性表、栈和队列、数组和字符串,树—学习笔记
- 黑马程序员------java学习笔记之数据结构
- #数据结构与算法学习笔记#PTA10:层次遍历叶节点(JAVA)
- Java学习笔记-5.常用数据结构
- 6Java学习笔记之数据结构——二叉树
- #数据结构与算法学习笔记#剑指Offer1:二维数组中的查找(JAVA)
- 4Java学习笔记之数据结构——队列
- 5Java学习笔记之数据结构——字符串String
- JAVA学习笔记 -- 数据结构
- JAVA学习笔记 -- 数据结构
- 数据结构(殷人琨版)学习笔记之单链表
- JAVA学习笔记 -- 数据结构
- JVM学习笔记(1、 基本结构;2、Java代码编译和执行的整个过程3、内存管理和垃圾回收 4、 内存调优 )
- Java存储结构-JVM规范学习笔记
- Java学习笔记---2.Java标识符和基本数据类型
- objective-c学习笔记第三章《objective-c循环结构与java中的区别》