Map的使用
public static void main(String[] args) {
Map<Integer,String> map=new HashMap<>();
map.put(1,"hello");
map.put(2,"word");
map.put(3,"heheh");
System.out.println(map);
System.out.println(map.get(1));
System.out.println(map.get(8));
//打印所有的key
for(Integer key:map.keySet()){
System.out.println(key);
}
//打印所有的value
for(String value:map.values()){
System.out.println(value);
}
//按key-value的映射打印
for(Map.Entry<Integer,String> entry:map.entrySet()){
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
Set的使用
public static void main(String[] args) {
Set<String> set=new HashSet<>();
set.add("hello");
set.add("word");
set.add("hehe");
set.add("hello");
System.out.println(set);
Iterator<String> it=set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
二叉搜索树
性质:
①若他的左子树不为空,则左子树上所有节点的值都小于根节点的值
②若他的右子树不为空,则右子树上所有节点的值都大于根节点的值
③它的左右子树也为二叉搜索树
public class BinarySearchTree {
public class Node{
int key;
Node left;
Node right;
public Node(int key) {
this.key = key;
}
}
//查找
private Node root=null;
public Node search(int key){
Node cur=root;
while(cur!=null){
if(cur.key==key){
return cur;
}else if(cur.key<key){
cur=cur.left;
}else{
cur=cur.right;
}
}
return null;
}
//插入
public boolean insert(int key){
if(root==null){
root=new Node(key);
return true;
}
Node cur=root;
Node parent=null;
while(cur!=null){
if(cur.key==key){
return false;
}else if(cur.key<key){
parent=cur;
cur=cur.left;
}else{
parent=cur;
cur=cur.right;
}
}
Node node=new Node(key);
if(key<parent.key){
parent.left=node;
}else if(key>parent.key){
parent.right=node;
}
return true;
}
//删除
public boolean remove(int key){
Node cur=root;
Node parent=null;
while(cur!=null){
if(cur.key==key){
removeNode(parent,cur);
return true;
}else if(cur.key<key){
parent=cur;
cur=cur.left;
}else{
parent=cur;
cur=cur.right;
}
}
return false;
}
private void removeNode(Node parent, Node cur) {
if(cur.left==null){
if(cur==root){
root=cur.right;
}else if(cur==parent.left){
parent.left=cur.right;
}else if(cur==parent.right){
parent.right=cur.right;
}
}else if(cur.right==null){
if(cur==root){
root=cur.left;
}else if(cur==parent.left){
parent.left=cur.left;
}else if(cur==parent.right){
parent.right=cur.left;
}
}else{
Node goatParent=cur;
Node goat=cur.right;
while(goat.left!=null){
goatParent=goat;
goat=goat.left;
}
cur.key=goat.key;
if(goat==goatParent.left){
goatParent.left=goat.right;
}else{
goatParent.right=goat.right;
}
}
}
}
哈希表
概念
顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(
l
o
g
2
N
log_2 N
log2N),搜索的效率取决于搜过
程中元素的比较次数。
理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素。 如果构造一种存储结构,通过某种函
数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快
找到该元素。
public class MyHashMap {
static class Node{
public int key;
public int value;
public Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private Node[] array=new Node[101];
private int size=0;//表示 当前hash表中的元素个数
private static final double LOAD_FACTOR=0.75;
private int hashFunc(int key){
return key%array.length;
}
//如果key已经存在就修改当前的value值
//如果key不存在 就插入新的键值对
public void put(int key,int value){
//需要把key映射成数组下标
int index=hashFunc(key);
//根据下标找到对应的链表
Node list=array[index];
//当前的key在链表中是否存在
for(Node cur=list;cur!=null;cur=cur.next){
if(cur.key==key){
//key已经存在直接修改value
cur.value=value;
return ;
}
}
//如果结束都没找到,相同的key节点,直接插入到指定链表的头部
Node newNode=new Node(key,value);
newNode.next=list;
array[index]=newNode;
size++;
if(size/array.length>LOAD_FACTOR){
resize();
}
}
//扩容
public void resize(){
Node[] newArray=new Node[array.length*2];
//把原来的hash'表中的元素搬运到新的数组上
for(int i=0;i<array.length;i++){
for(Node cur=array[i];cur!=null;cur=cur.next){
int index=cur.key%newArray.length;
Node newNode=new Node(cur.key,cur.value);
newNode.next=newArray[index];
newArray[index]=newNode;
}
}
}
//根据key查找指定的元素,如果找到返回对应的value值,如果没找到返回null
public Integer get(int key){
//先计算key对应的下标
int index=hashFunc(key);
//根据下标找到对应的链表
Node list=array[index];
//在链表中查找指定元素
for(Node cur=list;cur!=null;cur=cur.next){
if(cur.key==key){
return cur.value;
}
}
return null;
}
}