数据结构基础:栈和队列

栈和队列都属于抽象数据类型, 所以放到一起.


1. stack

stack很熟悉的一个地方就JVM的虚拟机栈.



我们知道, 在JVM里面的栈区, Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。


JAVA里面stack有已经实现的stack.

继承于Vector, 存储数据采用的是数组来保存数据:

protected Object[] elementData;  

至于使用很简单, Stack里面主要实现的有一下几个方法:

方法名返回类型说明
emptyboolean判断stack是否为空。
peekE返回栈顶端的元素。
popE弹出栈顶的元素
pushE将元素压入栈
searchint返回最靠近顶端的目标元素到顶端的距离。

使用参考:

http://shmilyaw-hotmail-com.iteye.com/blog/1825171


stack用链表的简单实现:

package com.cain.datastructrue;

/**
 * Created by wisdom on 15-10-14.
 */
public class Stack {

    private Node first;
    private int N;

    public boolean push(String string) {
        Node oldFirst = first;
        first = new Node();
        first.item = null;
        first.next = oldFirst;
        N++;
        return true;
    }

    public Object pop() {
        Object item = first.item;
        first.item = null;
        first = first.next;
        N--;
        return item;

    }
    
    private class Node {
        Node next;
        Object item;
    }
    /*
    * other function ....
    * */
    
}




2. 队列 (Queue)

队列是比较重要的一个内容.决定稍微深展下.

先来看看基础的FIFO队列

2.1  FIFO

队列(Queue)是只允许在一端进行插入,而在另一端进行删除(front删除, rear添加), 因此队列也称为"先进先出" 的线性表。

队列的实现方式有2种: 数组的存放形式和链表的存放方式;

数组的存放形式:

数组的存储形式下,存在溢出的现象:

①“下溢”现象
 当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
② "真上溢"现象
当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
③ "假上溢"现象
由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于内存中本分配的空间时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象



循环队列:
 如上图右边部分所示,这种头尾相接的顺序存储结构称为循环队列(circular queue)。
循环队列中需要注意的几个重要问题:
①队空的判定条件,队空的条件是front=rear;
②队满的判定条件,(rear+1)%QueueSize=front。QueueSize为队列初始空间大小。

我参考的是:

http://blog.csdn.net/wuwenxiang91322/article/details/12259099


把上面这两点理解了差不多就理解了队列的原理了, 我也简单的实现下循环队列:

public interface MyQueue<E> {

    public boolean enqueue(E obj);
    public  E dequeue();
    public int size();
    public boolean isEmpty();
}

package com.cain.mydatastructure;

/**
 * Created by wisdom on 15-11-6.
 */
public class CircleQueue<E> implements MyQueue<E> {
    private E[] elements;
    private int front;
    private int rear;
    private int size;
    private static final int DEFAULT_SIZE = 10;

    public CircleQueue() {
        this(CircleQueue.DEFAULT_SIZE);
    }

    public CircleQueue(int size) {
        elements = (E[]) new Object[size];

    }

    @Override
    public boolean enqueue(E obj) {
        if((rear+1)%elements.length==front){
                return false;
        }else {
            elements[rear]=obj;
            rear=(rear+1)%elements.length;
            size++;

        }
        return true;
    }

    @Override
    public E dequeue() {
        if (front==rear)
            return null;
        else {
            E data=elements[front];
            front=(front+1)%elements.length;
            size--;
            return data;
        }
    }

    @Override
    public int size() {
        
        //这样计算方式有问题
//        return (rear-front)&(elements.length-1);
////        if (rear>front)
////            return rear-front;
////        else
////            return elements.length-1;
        return size;

    }

    @Override
    public boolean isEmpty() {
        return front==rear;
    }
}


package com.cain.mydatastructure;

/**
 * Created by wisdom on 15-11-6.
 */
public class CircleQueueTest {
    public static void main(String[] args) {
        CircleQueue<String> queue=new CircleQueue<String>();
        queue.enqueue("hello");
        queue.enqueue("my");
        queue.enqueue("world");
        System.out.println(queue.size());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        
        //test for number 
        queue.enqueue("hello");
        queue.enqueue("my");
        queue.enqueue("world");
        queue.enqueue("hello");
        queue.enqueue("my");
        queue.enqueue("world");
        queue.enqueue("hello");
        queue.enqueue("my");
        queue.enqueue("world");
        //队列的初始值为10, 第10个放不进去的
        System.out.println(queue.enqueue("hello"));


        System.out.println(queue.size());

    }
}




队列的链表实现

在队列的形成过程中,可以利用线性链表的原理,来生成一个队列。

基于链表的队列,要动态创建和删除节点,这方面的效率当然没有数组高,但是它可以动态增长。

队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。所谓的动态创建,动态释放。因而也不存在溢出等问题。

代码实现参考:

http://blog.csdn.net/wuwenxiang91322/article/details/12303111



2.2  Deque


再来看看另外一种形式的队列Deque :       public interface Deque<E>  extends Queue<E> 

它是线性 collection,支持在两端插入和移除元素。

具体的看这个文章

http://uule.iteye.com/blog/2095650?utm_source=tuicool


--注意 Queue和Deque都只是接口, 还不能直接拿来用~  

那么直觉会问,JDK队列的现实现类有哪些呢?


2.3  其他部分

(参考的是  http://blog.sina.com.cn/s/blog_72ef7bea0101cy7h.html   )


JDK7之前已有的队列实现分为两类:用于一般用途的实现和用于并发的实现。

1)一般的用途

LinkedList实现了Queue接口,所以有先入先出队列的操作的方法;


PriorityQueue类是基于堆(数据结构)的优先队列(也叫堆),至于优先队列的原理看上个文章,

至于使用, 我简单写了个测试:

package com.cain.mydatastructure;

import java.util.Comparator;
import java.util.PriorityQueue;

/**
 * Created by wisdom on 15-11-8.
 */
public class PriorityQueueTest {

    private String country;
    private int population;


    public PriorityQueueTest(String country, int population) {
        this.country = country;
        this.population = population;
    }

    public int getPopulation() {
        return population;
    }

    public String getCountry() {
        return country;
    }

    public static void main(String[] args) {
        Comparator<PriorityQueueTest> comparator = new Comparator<PriorityQueueTest>() {
            @Override
            public int compare(PriorityQueueTest o1, PriorityQueueTest o2) {
                return o2.getPopulation() - o1.getPopulation();
            }
        };
            //5是初始容量大小而已,所以当你超过了这个大小,队列会有个增加的动作
        PriorityQueue<PriorityQueueTest> queueTests = new PriorityQueue<PriorityQueueTest>(5, comparator);

        queueTests.add(new PriorityQueueTest("china", 1000));
        queueTests.add(new PriorityQueueTest("America", 800));
        queueTests.add(new PriorityQueueTest("Japan", 600));
        queueTests.add(new PriorityQueueTest("Singepore", 200));
        queueTests.add(new PriorityQueueTest("Canada", 700));
//        queueTests.remove();
        while (true) {

            PriorityQueueTest test = queueTests.poll();
            if (test != null) {
                System.out.println(test.getCountry() + ", and population is:" + test.getPopulation());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else
                break;
        }


    }

}

打印结果:

china, and population is:1000
America, and population is:800
Canada, and population is:700
Japan, and population is:600
Singepore, and population is:200


使用可以参考:

http://www.importnew.com/6932.html



2)并发队列实现

涉及到线程的并发, 这个结合线程来理解更好, 以后再写个文章具体分析这些队列





内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
内容概要:本文档聚焦于“直流电机双闭环控制Matlab仿真”,系统阐述了基于Matlab/Simulink平台实现直流电机双闭环控制系统(主要包括速度环与电流环)的设计与仿真全过程。通过构建直流电机的数学模型,结合PI控制器进行调控,实现对电机转速电枢电流的高精度动态控制,验证控制策略的稳定性与响应性能。文档详细介绍了仿真模型的搭建流程、关键参数的整定方法、系统动态波形的分析手段以及仿真结果的有效性验证,体现了经典自动控制理论在实际电机系统中的工程应用,是电机控制与电力电子技术相结合的典型研究案例。; 适合人群:具备自动控制原理、电机与拖动基础、电力电子技术Matlab/Simulink仿真能力的电气工程、自动化、机电一体化等专业的本科生、研究生及从事电机驱动系统研发的工程技术人员。; 使用场景及目标:①作为高校课程设计或实验教学材料,帮助学生深入理解双闭环调速系统的工作机理与工程实现;②服务于科研项目,为新型电机控制算法(如滑模、模糊PID等)的开发与性能对比提供基础仿真验证平台;③作为工业界产品前期设计的仿真工具,用于评估不同控制策略在动态响应、抗干扰能力稳态精度方面的可行性。; 阅读建议:建议读者在学习过程中紧密结合自动控制理论知识,亲手在Simulink环境中搭建完整的双闭环仿真模型,通过反复调整PI控制器的比例与积分参数,观察并分析转速、电流的阶跃响应曲线,从而深刻理解反馈控制的本质、系统稳定性条件以及参数整定对动态性能的影响,进而掌握电机控制系统的设计精髓。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值