Tesk03:栈和递归

理论部分

  • 用数组实现一个顺序栈。
  • 用链表实现一个链栈。
  • 理解递归的原理。

栈实现接口

public interface Stack {
    // 入栈
    void push(E data);
    // 出栈
    E pop();

    boolean isEmpty();

    int size();

    // 查看栈顶元素
    E peek();
}

顺序栈代码实现

public class ArrayStack implements Stack {
    private E[] datas;
    private int size;
    //private int index;

    public ArrayStack(){
        this(20);
    }
    public ArrayStack(int capacity){
        this.datas = (E[]) new Object[capacity];
        size = 0;
    }
    public int capability(){
        return datas.length;
    }

    // 扩大的数组的长度
    private void resize(int capability){
        if(capability <= 0)
            return;
        E [] temps = (E[]) new Object[capability];

        for(int i = 0; i < size; i ++)
            temps[i] = datas[i];

        datas = temps;
    }

    @Override
    public void push(E data) {
        if(size == datas.length)
            resize(datas.length * 2);

        datas[size++] = data;
    }

    @Override
    public E pop() {
        if(size == datas.length/4)
            resize(datas.length/2);
        E data = datas[size-1];
        datas[--size] = null;
        return data;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public E peek() {
        return datas[size-1];
    }

    public void print(){
        for(int i =0 ;i < size; i++)
            System.out.print(datas[i] + " ");
        System.out.println();
    }
}

链表栈d代码实现


public class LinkedStack implements Stack{

    private class Node{
        E data;
        Node next;
        Node(E data){
            this(data, null);
        }
        Node(E data, Node next){
            this.data = data;
            this.next = next;
        }
    }

    private Node head;
    private int size;

    LinkedStack(){
        head = null;
        size = 0;
    }

    @Override
    public void push(E data) {
        if(head == null)
            head = new Node(data);
        else
            head = new Node(data, head);

        size ++;
    }

    @Override
    public E pop() {
        E data = head.data;
        head = head.next;
        size --;
        return data;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public E peek() {
        return head.data;
    }
}

练习部分

1. 根据要求完成车辆重排的程序代码

假设一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1n,货运列车按照第n站至第1站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1n的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。

我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k个(k=3)缓冲铁轨H1H2H3。开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1n的次序离开转轨站(通过出轨处)。在图(a)中,n=9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。图(b)给出了按所要求的次序重新排列后的结果。

编写算法实现火车车厢的重排,模拟具有n节车厢的火车“入轨”和“出轨”过程。

代码实现

public class Solution {
    public static boolean resort(int[] train, int [] newTrain,int k) {
        int outNum = 1; // 入轨的顺序号
        int index = 0; // 新火车数组的下标
        boolean flag ; // 控制循环
        Stack[] buffer = new Stack[k];
        for(int i = 0; i < k; i++){
            buffer[i] = new Stack();
        }

        for(int i = 0; i < train.length; i ++){
            if(train[i] == outNum){
                System.out.println(train[i] + "号出轨,进入新火车排序轨道");
                newTrain[index] = outNum;
                index ++;
                outNum ++;
                // 检测下缓冲区出轨情况
                do {
                    flag = false;
                   // boolean flag2 = false;
                    for(int j = 0; j < buffer.length; j ++){
                        if (buffer[j].size() == 0)
                            continue;
                        if(buffer[j].peek() == outNum){
                            newTrain[index] = buffer[j].peek();
                            index ++;
                            System.out.println(buffer[j].pop() + "号车出缓冲轨,进入新火车排序轨道");
                            outNum ++;
                            flag = true;
                        }
                    }
                }while (flag);

            }else{
                // 放入缓冲区
                if(!hold(buffer, train[i]))
                    return false;
            }
        }

        train = newTrain;
        return true;
    }

    private static boolean hold(Stack[] buffer, int carriage){
        int index = -1;

        for(int i = 0; i < buffer.length; i ++){
            if (buffer[i].size() == 0){
                index  = i;
                break;
            }else if(buffer[i].peek() >= carriage){
                index = i;
                break;
            }
        }
        if(index == -1)
            return false;

        buffer[index].push(carriage);
        return true;
    }


    public static void main(String[] args){
        int [] train = {6,8,5,3,1,9,2,4,7};
        int [] newTrain = new int[train.length];
        int k = 3;

        boolean falg = resort(train, newTrain,3);
        System.out.println(falg);

        if(falg == true) {
            for (int carriage : newTrain)
                System.out.print(carriage + " ");
            System.out.println();
        }
    }

}


你可能感兴趣的:(Tesk03:栈和递归)