看了程序人生一篇文章:如何实现可以获取最小值的栈。自己思考,实现了一下

近来学习了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寻找对应的技术要点–选取合适方法写出基本代码–验证–业务逻辑整体进行优化

也不算是自己独立解决的问题吧,但是整个过程回想起来,印象很深。
和任何知识一样,计算机这门应用技术,没有扎实的基础,没有墙裂的爱好和执着,没有大量的动手锻炼和思考,摸索。那就很难受了。希望一切顺利吧,能找到一生愿意陪伴的技术,找到自己。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值