上一篇中分享了物理结构中的线性结构数组和链表的相关内容,在本篇中将继续分享逻辑结构中的线性结构栈、队列和散列表相关特性及代码示例。
栈结构,栈的特性在总述篇已经描述过,是先进后出。即当新元素进入栈后成为新的栈顶元素,出栈时栈顶元素先出栈,后续元素依次出栈,栈底元素最后出栈,栈结构可以用数组实现也可用链表实现。
//Java中栈的实现是Stack类,其底层是用数组实现的
Stack<Integer> stack = new Stack<Integer>();
//判断栈是否为空
stack.isEmpty();
//push和add都可以向栈中添加元素,push返回添加的元素,add返回boolean是否添加成功
stack.push(1);
stack.push(2);
stack.add(3);
//返回并移除栈顶元素
Integerpop=stack.pop();
//返回栈顶元素但不移除
Integerpeek=stack.peek();
//遍历输出栈中的值
for(Integeri:stack){
System.out.println(i);
}
队列结构,队列的特性是先进先出。即当新元素进入队列时放在队尾位置,出队列时队头元素先出,后续元素依次出队列,队尾元素最后出队列,队列可用数组实现也可用链表实现。
//linkedlist是queue接口和list接口的实现类
Queue<Integer>queue=newLinkedList<Integer>();
//在队尾插入元素0
((LinkedList<Integer>)queue).add(0);
//在索引为1的位置插入元素1
((LinkedList<Integer>)queue).add(1,1);
//在队尾插入元素2
//offer,add区别:
//一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
//这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false
queue.offer(2);
//获取队列索引0位置的元素
((LinkedList<Integer>)queue).get(0);
//在队尾插入元素3
((LinkedList<Integer>)queue).push(3);
//移除队头元素
((LinkedList<Integer>)queue).pop();
//遍历输出队列中的值
for(Integeri:queue){
System.out.println(i);
}
//poll和remove都是移除元素,不过当是空队列时poll方法会返回null,remove方法会抛异常
queue.poll();
queue.remove();
//element() 和 peek() 用于在队列的头部查询元素,当时空队列时peek返回null,element抛异常
queue.peek();
queue.element();
散列表或叫哈希表,其特性是以键值对形式存储数据。当有新键值对要存储时,会先对键进行哈希函数,得到对应的哈希码,在哈希码对应的位置存储值。但是这可能会发生哈希冲突的问题,相应的有如下四种解决方案:
开放寻址法:当一对键值对来临发现对应的哈希码处已经存在值了,则寻找该哈希码的下一位置进行存储,如果下一位置也有值存在,则再向下一位置寻找,以此类推。
再哈希法:即使用不同的哈希函数进行寻址。
链寻址法:将所有key相同的值存储在一个单链表中。
溢出表法:即设计两个表,基础表和溢出表,先往基础表中存储,若对应的哈希码处有值存在,则将其依次存入溢出表中。
散列表可用数组实现也可用链表实现。
//HashMap键最多只有一个为null,值可以多个为null
Map<String,String> map = new HashMap<String, String>();
//LinkedHashMap内部维护了一个双向链表,可以保持顺序
Map<String,String>map1=newLinkedHashMap<String,String>();
//TreeMap可以根据键排序
Map<String,String>map3=newTreeMap<String,String>();
//Map中的键值对实际上是以Entry数组的形式存在的
Setset=map.entrySet();
//Map存储键值对
map.put("key1","value1");
map.put("key2","value2");
//map移除键值对
map.remove("key1");