22.1.9 链表

22.1.9 链表

1. 哈希表

1)哈希表在使用层面上可以理解为一种集合结构

2)如果只有key,没有伴随数据value,可以使用HashSet结构(C++中叫UnOrderedSet)

3)如果既有key,又有伴随数据value,可以使用HashMap结构(C++中叫UnOrderedMap)

4)有无伴随数据,是HashMap和HashSet唯一的区别,底层的实际结构是一回事 5)使用哈希表增(put)、删(remove)、改(put)和查(get)的操作,可以认为时间复杂度为 O(1),但是常数时间比较大

6)放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小

7)放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西内存地 址的大小(8bits)

  • code:

    public static void main(String[] args)
{
HashSet<Integer> hs = new HashSet<>();
hs.add(3);
hs.add(4);
System.out.println(hs.contains(3)) ;
hs.remove(3);
System.out.println(hs.contains(3)) ;

HashMap<Integer,String> hm = new HashMap<>();
hm.put(1,"Tx");
hm.put(2,"Zmy");
System.out.println(hm.get(1)) ;
System.out.println(hm.containsKey(1)) ;
System.out.println(hm.containsValue("zmy")) ;
hm.put(1,"Xt");//put函数可以用来修改hashmap中的值
System.out.println(hm.get(1)) ;
System.out.println(hm.containsKey(1)) ;
}
  • 运行结果:

true
false
Tx
true
false
Xt
true

 

2. 有序表

有序表的概念:

1)有序表在使用层面上可以理解为一种集合结构

2)如果只有key,没有伴随数据value,可以使用TreeSet结构(C++中叫OrderedSet)

3)如果既有key,又有伴随数据value,可以使用TreeMap结构(C++中叫OrderedMap)

4)有无伴随数据,是TreeSet和TreeMap唯一的区别,底层的实际结构是一回事 5)有序表和哈希表的区别是,有序表把key按照顺序组织起来,而哈希表完全不组织

6)红黑树、AVL树、size-balance-tree和跳表等都属于有序表结构,只是底层具体实现 不同

7)放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小

8)放入哈希表的东西,如果不是基础类型,必须提供比较器,内部按引用传递,内存占 用是这个东西内存地址的大小

9)不管是什么底层具体实现,只要是有序表,都有以下固定的基本功能和固定的时间复 杂度

有序表的基本操作

1)void put(K key, V value):将一个(key,value)记录加入到表中,或者将key的记录 更新成value。

2)V get(K key):根据给定的key,查询value并返回。

3)void remove(K key):移除key的记录。

4)boolean containsKey(K key):询问是否有关于key的记录。

5)K firstKey():返回所有键值的排序结果中,最左(最小)的那个。

6)K lastKey():返回所有键值的排序结果中,最右(最大)的那个。

7)K floorKey(K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中, key的前一个。

8)K ceilingKey(K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中, key的后一个。 以上所有操作时间复杂度都是O(logN),N为有序表含有的记录数

  • code:

TreeMap<Integer, String> treeMap1 = new TreeMap<>();

TreeSet<类对象> treeSet = new TreeSet<>(new NodeComparator);//需要自己提供比较器。

3. 单链表

  • 单链表的节点结构

Class Node

{

V value;

Node next;

}

 

由以上结构的节点依次连接起来所形成的链叫单链表结构。

  • 双链表的节点结构

Class Node

{

V value;

Node next;

Node last;

}

 

由以上结构的节点依次连接起来所形成的链叫双链表结构。

面试时链表解题的方法论

1)对于笔试,不用太在乎空间复杂度,一切为了时间复杂度

2)对于面试,时间复杂度依然放在第一位,但是一定要找到空间最省的方法 重要

 

技巧:

1)额外数据结构记录(哈希表等)

2)快慢指针

//快慢指针核心代码;
Node n1 = head;
Node n2 = head;
while(n2.next !=null && n2.next.next!=null)
{
   n1 = n1.next;
   n2 = n2.next.next;
}
//慢指针走一步,快指针走两步
//调好快慢指针后再进行需求操作。
  • example:

  • 利用快慢指针判断单链表是否有环,并返回环的第一个节点:

  • 思想:快指针每次走两步,慢指针每次走一步,若快慢指针第相遇,则说明这个单链表有环,然后快指针回到头结点的位置,快指针每次走一步,慢指针每次也走一步,快慢指针再次相遇的位置就是环的第一个节点。

  • 注意:单链表只有一个next指针,也就是说节点后面只会跟一个节点。

  • code:

Node n1 = head;
Node n2 = head;
while(n1 != n2)
{
   if(n2.next.next == null || n2.next == null)
       return null;//没有环
   n2 = n2.next.next;
   n1 = n1.next;
}

n2 = head;
while(n2 != n1)
{
   n2 = n2.next;
   n1 = n1.next;
}//当n1和n2相遇循环结束
return n1;

 

posted @ 2022-01-10 16:05  张满月。  阅读(152)  评论(0编辑  收藏  举报