数据集合是编程中常用的逻辑,链表是在数据结构中经常被用到和考察,JDK util 包中提供了Queue 接口,
LinkedList、LinkedHashSet、LinkedHashMap<K,V>实现。
显而易见,linkedHashSet 是以LinkedHashMap<K,V> 为基础来实现的。
/**
* Constructs a new, empty linked hash set. (This package private
* constructor is only used by LinkedHashSet.) The backing
* HashMap instance is a LinkedHashMap with the specified initial
* capacity and the specified load factor.
*
* @param initialCapacity the initial capacity of the hash map
* @param loadFactor the load factor of the hash map
* @param dummy ignored (distinguishes this
* constructor from other int, float constructor.)
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
之前在做数据采集的时候,自己动手写了一个采集程序,虽然过程曲折,但对于后期对于开源爬虫的使用很有帮助,当你自己实现了一个算法,简单引擎,再去看同类就有一种俯视的视角, 不要迷信权威 ,毕竟计算机行业发展还处于起步阶段。
什么是链表
接下来 先大概说一下链表,链表顾名思义,是由一个一个节点组成的一个数据链 ,前一个节点next 指向后一个节点,遍历的时候,根据头节点顺序找到尾节点。
链表示意图:
链表的实现在不同开发语言中细节不同 (),但链表的定义有一个通用的标准,引用《算法导论》中的定义
链表 linked list 是一种这样的数据结构, 其中的各对象an线性顺序排列,数组的线性顺序是由数组的下标决定,然而与数组不同的是,链表的顺序是由各个对象的指针决定的,链表为动态集合提供一种简单而灵活的表示方法。
支持 insert 、delete、pop 常用操作方法
链表节点
链表节点 首先能保存数据,这里简单选择了object 对象
然后节点中需要指向另一个节点
class Node {
private String name;
private Object data;
private Node next;
public Node(String name, Object data, Node next) {
this.name = name;
this.data = data;
this.next = next;
}
public boolean hasNext() {
if (null == next) {
return false;
} else {
return true;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
这里我选择了inner class
链表的简单实现
public class LinkedList {
/**
* 头节点
*/
private Node head;
/**
* 判断链表是否为空
*
* @return
*/
private Boolean isEmpty() {
if (null == head) {
return true;
} else {
return false;
}
}
/**
* 获取头节点
*
* @return
*/
public Object getHead() {
if (null == head) {
return null;
} else {
return head.getData();
}
}
/**
* 增加节点
*/
public boolean insertData(Object data) {
if (isEmpty()) {
head = new Node("first", data, null);
} else {
Node temp=head;
while (temp.hasNext()) {
temp = temp.getNext();
}
temp.setNext(new Node("last", data, null));
}
return true;
}
/**
* 删除节点
*/
public boolean deleteData(Object data) {
if (isEmpty()) {
return false;
} else {
/**
* 如果是头节点 直接删除返回
*/
if (head.getData() == data) {
head = head.getNext();
return true;
} else {
while (head.hasNext()) {
Node temp = head.getNext();
if (temp.getData() == data) {
head.setNext(temp.getNext());
break;
}
}
return true;
}
}
}
}
链表翻转
链表翻转是一道常见的算法题目,比较简单
下班给出一种简单的解题思路:
链表由于只能指向后续节点,没有下标所以要遍历链表 截断,所有你需要 借用三个新的节点
起名为:
航行节点,用于遍历链表
head 节点 用户找到新的翻转节点
rail 节点 用户找到原来的节点
a->b->c->d
sail
head
tail
sail->a->b->c->d
head->a sial->b-c-d
tail=b
head->b->a sial-c-d
Node fake = new Node("fake", 0, null);
Node sail = new Node("sail", 0, d);
while (sail.hasNext()) {
Node temp = sail.getNext();
sail.setNext(sail.getNext().getNext());
if (fake.hasNext()) {
temp.setNext(fake.getNext());
fake.setNext(temp);
} else {
fake.setNext(temp);
temp.setNext(null);
}
}
while (fake.hasNext()) {
System.out.println(fake.getNext().getData());
fake = fake.getNext();
}