近来学习了java,对数据结构很感兴趣。
今天看到看了程序人生一篇文章:如何实现可以获取最小值的栈。自己按着哥们的代码,查了jdk1.8的关于数据结构的api。又深入学习比较一下各种数据结构,觉得LinkedList,TreeMap的用法和方法很适合这个功能实现,就自己尝试优化了一下。
然后,实现了基本的入栈和弹栈的功能,并能输出栈中的最小值。
半下午,写出来了心里很高兴,就分享在这里,还请指导。。。
TreeMap<K,V>,我理解它为一个自动排序的Map。就是说存放的数据可以乱序,但它会在内部按照key的顺序排序。
可以看下面的测试类中,我随机放入的数据输出后,按照key的大小排序了。
package day1001_LinkedList;
import java.util.TreeMap;
/*
* 测试TreeMap的用法
*/
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Integer,String> tm = new TreeMap<Integer,String>();
tm.put(105, "小明");
tm.put(5, "dnjnd");
System.out.println(tm.size());//2
tm.put(4, "akdnalk");
tm.put(10, "asnjdlk");
System.out.println(tm.size());//4
System.out.println(tm.firstEntry());//4=akdnalk
System.out.println(tm);//{4=akdnalk, 5=dnjnd, 10=asnjdlk, 105=小明}
}
}
下面是主程序的代码:
package Stack;
import java.util.LinkedList;
import java.util.TreeMap;
/**
* 通过linkedList+TreeMap实现栈的后进先出
* put压栈,pop弹栈
* @author wzz
*
*/
public class LinkedListStack {
private LinkedList<Integer>data=new LinkedList<>();
private TreeMap<Integer,Integer>mins=new TreeMap<>();
//添加数据
public void push(int num){
data.add(num);//将指定元素添加到尾部
doMinusMap(num);
}
public void doMinusMap(int num){
//在最小值的map中放置数据,首次的话就直接放进去
if(mins.size()==0){
mins.put(num, 1);
}
if(num==mins.firstKey()){
//如果又添加了一个最小值,就在原有基础上加一
mins.replace(num, mins.get(num)+1);
}else if(num<mins.firstKey()){
//如果第一排列的key值还小,就在map里再放一个entry,否则的话,就和treeMap中最小的数比较
mins.put(num, 1);
}
}
//弹栈的时候,根据后进先出的原则,从双向链表中删除头数据
public void pop(){
//如果栈为空,抛出异常
if(data.size()==0){
throw new RuntimeException("栈为空");
}
//然后弹出数据,就是第一个数据
//先得到这个数据
Integer in = data.get(0);
if(mins.get(in)!=0){//如果有这个数字的话,就次数减一
mins.replace(in, mins.get(in)-1);
if(mins.get(in)==0){
mins.remove(in);//如果mins的map中in的次数为0,就移除这个entry
}
}//如果没有保存在map中,直接pop
data.poll();//删除头数据
}
public String getMin(){
Integer minsKey = mins.firstKey();
return "最小值:"+minsKey+"出现了"+mins.get(minsKey)+"次";
}
}
测试代码如下:
package Stack;
public class StackDemo {
public static void main(String[] args) {
LinkedListStack stack = new LinkedListStack();
stack.push(4);
stack.push(2);
stack.push(3);
stack.push(2);
stack.push(4);
stack.push(2);
stack.push(1);
stack.push(2);
stack.pop();
System.out.println(stack.getMin());//最小值:1出现了1次
}
}
应该还有bug,但是一个简单的实现功能基本实现了。如果有错误和优化,还请大家赐教。因为:对bug爱的深沉。
.
今天写代码的整个思路可以说是很难得了:
遇到一个感兴趣的问题–明白基本原理+基本逻辑–还要写出来(结果写不出来,而且感觉原文章思路有点不了解)–查找api寻找对应的技术要点–选取合适方法写出基本代码–验证–业务逻辑整体进行优化
也不算是自己独立解决的问题吧,但是整个过程回想起来,印象很深。
和任何知识一样,计算机这门应用技术,没有扎实的基础,没有墙裂的爱好和执着,没有大量的动手锻炼和思考,摸索。那就很难受了。希望一切顺利吧,能找到一生愿意陪伴的技术,找到自己。