前言:
大家好,我是春风
今天继续刷左神的算法视频,前面刷完了入门的查找和排序算法,也对排序算法做了一些总结。 现在开始刷结构部分,第一个结构是哈希表,然后是链表。哈希表的应用在Java中有现成的map结构,链表更多的是一些解法上的规律。
一、哈希表
- HashMap:内部结构是数组+链表+红黑树,之前有单独说过hashmap的结构。
- HashSet:和hashmap的结构一样,只是不带value,相当于是只有hashmap的key的那部分集合。
- TreeMap:有序的hashmap
- TreeSet:有序的hashset
如果哈希表内存储的是基本类型,比如:
Set<String> set = new HashSet<String>();
则内部是值传递,即存储的时候会拷贝当前的值,为一个新的string。如果是对象,则就是存储该对象的地址。
二、链表
链表分单向链表和双向链表,一般在Java中新建一个节点Node类,单向链表,类里包含:
private LinkedNode next;
private String value;
双向链表多一个指向前一个的指针:
private LinkedNode next;
private LinkedNode pre;
private String value;
例题:
1. 反转一个链表
方法一、使用栈,遍历链表,依次入栈,然后依次出栈,就能很简单的反转整个链表,空间复杂度O(N), 时间复杂度O(N)
方法二、头插法 遍历链表,每次将当前节点放到头节点的后面,这样最后返回回来的头节点,就是反转后的头节点。时间复杂度O(N),空间复杂度O(1)
比如链表 1->2->3->4->5 遍历到节点1,不用动;遍历到节点2,先将当前cur移到cur.next,这样其实链表就分成了两部分,然后使2指向1,最后将head节点移到2位置;
cur到了节点3,中间节点temp记录下来,cur移到cur.next,然后将3节点指向头节点,头结点移动到3节点的位置;
移到最后一个节点,则返回的头结点链表就是逆序的了。
代码:
class LinkedNode{
private LinkedNode next;
private String value;
}
public static LinkedNode reverseList(LinkedNode head) {
if (head == null) {
return null;
}
LinkedNode last = head;// 翻转后的最后一个节点,也就是翻转前的第一个节点
LinkedNode cur = head.next;
LinkedNode temp;
while (cur != null) {
temp = cur;//中间节点记录下当前遍历到的位置
cur = cur.next; //当前节点移到下一个,为下次做准备,同时将链表一分为二,head到temp,cur到末尾
temp.next = head; //头插,将当前遍历到的节点插入到头节点的前面