算法学习系列(四)——栈和队列

本文是算法学习系列的第四篇,主要探讨栈(LIFO)和队列(FIFO)的数据结构。通过实例讲解了栈在逆置数组、火车重排和汉诺塔问题中的应用,并分析了在解决火车重排问题时使用栈的思路。同时,介绍了链表和数组实现队列的基本方法。
摘要由CSDN通过智能技术生成

4.1 栈

栈,LIFO(last-in-first-out),先进后出

一些可以利用栈实现的算法:

4.1.1 逆置数组

代码是这样的:

import java.util.Stack;

public class Main {
    public static  void main(String args[]){
        int array1[]={1,2,3,4,5,6};
        Stack<Integer> stack = new Stack<Integer>();
        for(int i=0;i<array1.length;i++){
            stack.push(array1[i]);
        }
        for(int i=0;i<array1.length;i++){
            System.out.print(array1[i]+" ");
        }
        System.out.println();
        for(int i=0;i<array1.length;i++){
            array1[i] = stack.pop();
        }
        for(int i=0;i<array1.length;i++){
            System.out.print(array1[i]+" ");
        }

    }


}

输出:

在写的过程中发现了自己的一点问题:

第一次写的时候是这样的用的是stack的大小来作为循环的上限,这样导致输出的内容变成了,出现这个的原因是因为,在stack.pop()的过程中,stack的大小不断被-1,导致没有循环完就结束了!属实不够仔细!

4.1.2 火车重排

这个问题拿数组明明很好写,用栈就很麻烦))

问题:一列货运火车从出发站出发时火车上一共有n节车厢,编号分别是1到n,运货的各节车厢是在入轨上时是随机的顺序,火车头在出轨处,现在要将各节车厢按编号从大到小挂到车头上,其中在入轨与出轨之间有k条缓冲铁轨,将通过缓冲铁轨完成本次的火车车厢的重排。

在我的实现代码中, 假设有7节车厢,1条缓冲轨,我的思路是,将车厢的顺序保存为一个数组(此步其实多余),声明三个栈,分别是未排序的火车train、一条缓冲轨道cache、排序后的火车output。首先判断train的栈首符合进入output的条件吗,符合的话压入output,不符合则进入cache,一直不断地判断和压出,直到train中没有元素为止,然后对cache中的元素进行相同操作,直到cache中没有元素,output中元素的个数和数组的元素个数相同时停止,输出output。

以下是代码:

import java.util.Stack;

public class Main {
    public static  void main(String args[]){
        //假设有1个缓冲轨道,进入的列车顺序为7532461
        Stack train = new Stack();
        int trainarray[] = {7,5,3,2,4,6,1};
        for(int i=0;i<trainarray.length;i++){
            train.push(trainarray[i]);
        }
        //System.out.println(train.get(train.size()-1));
        int flag = 0;
        int first = 0;
        Stack cache = new Stack();
        Stack output = new Stack();
        while((output.size())!=trainarray.length){
            while(flag == 0){
                if((train.size())==0){
                    flag = 1;
                }else {
                    if(train.get(train.size()-1).equals(first+1)){
                        output.push(train.pop());
                        first++;
                    }else {
                        cache.push(train.pop());
                    }
                }

            }
            while(flag==1){
                if(cache.size()==0){
                    flag = 0;
                }else {
                    if(cache.get(cache.size()-1).equals(first+1)){
                        output.push(cache.pop());
                        first++;
                    }else {
                        train.push(cache.pop());
                    }
                }
            }
        }
        int m = output.size();
        for(int i=0;i<m;i++){
            System.out.print(output.pop()+" ");
        }


    }


}

输出内容:

4.1.3 汉诺塔

汉诺塔是老熟人啦!三根柱子,第一根有从小到大的一堆不同大小的盘子,每次将一个盘子从一个柱子上移到另一根,目标是将盘子按照从小到大的顺序在新的柱子上叠起来,注意大的盘子不可以堆在小的盘子上!

书上写到:“通常,如果有N个盘子要移动的话,步骤的数量是2^N-1。如果有35个盘子玩汉诺塔而每步需要一秒来实现的话,将会花费1000年”

汉诺塔除了栈的方案还可以用递归实现,会在后面学习递归的时候实现一次~

4.2 队列

4.2.1链表实现队列

代码参考了这篇



public class Main {
    public static  void main(String args[]){
        //队列的链表实现
        Queue<String > list = new Queue<String >();
        list.enterQueue("hahahhaha");
        list.enterQueue("xiiixixiixi");
        list.enterQueue("12121212");

        System.out.println(list.DeQueue().getValue().toString());
        System.out.println(list.DeQueue().getValue().toString());
        System.out.println(list.DeQueue().getValue().toString());


    }

    //构建链表
    public static class LinkedList<T>{
        private T value;//链表元素的值
        private LinkedList<T> next;//指向下一个元素的指针

        public T getValue() {
            return value;
        }

        public void setValue(T value) {
            this.value = value;
        }

        public LinkedList<T> getNext() {
            return next;
        }

        public void setNext(LinkedList<T> next) {
            this.next = next;
        }
    }

    //构建队列,队列是先入先出的
    public static class Queue<T>{
        private LinkedList<T> first = null;//链表头
        private LinkedList<T> last = null;//链表尾
        private int size =0;//链表长度

        public boolean enterQueue(T newElement){
            LinkedList<T> element = new LinkedList<>();
            element.setValue(newElement);
            if(size==0){
                first = element;
                size++;
                return true;
            }
            if(last==null){
                last = element;
                first.setNext(last);
            }else {
                last.setNext(element);
                last = element;
            }
            size++;
            return true;
        }

        public LinkedList<T> DeQueue(){
            if(first==null){
                return null;
            }else {
                LinkedList<T> result=first;
                first = first.getNext();
                return result;
            }
        }

        public int getSize(){
            return size;
        }

        public LinkedList front(){
            return first;
        }
    }
}

结果为:

4.2.2 数组实现队列

这也太难顶了,就不自己实现了)))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值