LRU页面置换算法--基于栈

前言

使用栈实现LRU页面置换算法的代码
LRU页面置换算法可以使用基于计数器,或者基于栈两种方式进行实现
基于计数器
若有不当之处,请您指出,您的指点是我的荣幸

代码实现

这里使用双向链表来实现栈


import java.util.Scanner;

/**
 * LRU页面置换算法--基于栈
 */

public class LRUStack {


    public static void main(String[] args) {

        //当链表未达到指定长度时,用来表示链表的长度
        int length = 0;

        //表示缺页错误次数
        int pageFault=0;

        //先创建一个头结点
        StackSlot head = new StackSlot(null, -1, null);

        //表示每次页面进来时,若需要创建节点,该变量作为中转节点
        StackSlot nowNode = null;

        //表示头结点后的第一个节点
        StackSlot firstNode=null;

        //表示最后一个节点
        StackSlot lastNode=null;

        //当需要进行链表节点的变换的时候,以此作为中转
        StackSlot tempNode=null;

        Scanner sc=new Scanner(System.in);
        System.out.println("请输入页面的数量");
        //定义页面数量
        int num=sc.nextInt();

        System.out.println("请输入栈的深度");
        //定义栈的深度(其实也就是帧数组的长度)
        int frame=sc.nextInt();

        //创建页面数组
        int[] pageArr=new int[num];
        System.out.println("请输入页面序列");

        //初始化页面数组
        // 1,2,3,4,3,5,3,8,4,7,2,1,0,9,12,33,2,1,6,2,1
        for(int i=0;i<num;i++){
            pageArr[i]=sc.nextInt();
        }

        //构建一个链表
        for (int i = 0; i < num; i++) {

            //此时链表未达到指定长度
            if(length==0){
                //第一个节点

                //新建链表
                nowNode=new StackSlot(head,pageArr[i],null);
                //链接
                head.next=nowNode;
                //链表长度+1
                length++;
                //缺页错误次数+1
                pageFault++;
            }else if(length==1){
                //此时链表有了一个节点

                //判断链表中是否有相同页码的页
                tempNode=hasSame(head,pageArr[i]);
                //如果没有相同页码的页
                if(tempNode==null){
                    //如果没有页码相同的页

                    lastNode=getLast(head);
                    //新建一个节点
                    nowNode=new StackSlot(lastNode,pageArr[i],null);
                    //链接到链表末尾
                    lastNode.next=nowNode;
                    length++;
                    pageFault++;
                }
            }else if(length<frame){
                //此时链表中已经有两个或两个以上的节点,但是未满
                //查看是否有页码相同的页,若有就将该节点返回
                tempNode=hasSame(head,pageArr[i]);
                //获取最后一个节点
                lastNode=getLast(head);

                //如果没有页码相同的页
                if(tempNode==null){
                    //如果链表中没有页码相同的页

                    //新建一个节点
                    nowNode=new StackSlot(lastNode,pageArr[i],null);
                    //拿到最后一个节点
                    lastNode.next=nowNode;
                    //链表长度+1
                    length++;
                    pageFault++;
                }else{
                    //如果有相同页码的页
                    //如果页码相同的页不是末尾节点的话
                    if(tempNode.page!=lastNode.page){

                        //将该节点从链表中删除
                        tempNode.pre.next=tempNode.next;
                        tempNode.next.pre=tempNode.pre;

                        //将该节点链接到末尾
                        lastNode.next=tempNode;
                        tempNode.pre=lastNode;
                        tempNode.next=null;
                    }
                }
            }else{
                //此时链表已经达到指定长度了,接下来发生缺页错误将进行页面的置换

                //检验链表中是否有相同页码的页
                tempNode=hasSame(head,pageArr[i]);
                //拿到最后一个节点
                lastNode=getLast(head);
                //如果没有页码相同的页,就要淘汰掉头结点后的第一个节点
                if(tempNode==null){
                    //拿到原先的头结点之后的第一个节点
                    firstNode=getFirst(head);

                    //新建一个节点
                    nowNode=new StackSlot(lastNode,pageArr[i],null);


                    //淘汰第一个节点
                    head.next=firstNode.next;
                    firstNode.next.pre=head;

                    //将新建节点链接到末尾
                    lastNode.next=nowNode;

                    //缺页错误次数+1
                    pageFault++;

                }else{
                    //如果已经有了相同的页,将该页调到末尾去!
                    //将该节点从链表中删除
                    tempNode.pre.next=tempNode.next;
                    tempNode.next.pre=tempNode.pre;

                    //链接到末尾
                    lastNode.next=tempNode;
                    tempNode.pre=lastNode;
                    tempNode.next=null;
                }
            }
        }

        //打印链表
        myPrint(head,pageFault);

    }

    //查看当前链表中是否已经有此页
    public static StackSlot hasSame(StackSlot head, int page) {
        while (head!= null) {
            if (head.page == page) {
                //如果已经有相同的页面在帧数组当中就返回
                return head;
            }
            head = head.next;
        }
        //没有就返回null
        return null;
    }

    //进行链表的变换的时候,需要将节点链接到最后,所以需要获得最后一个节点
    public static StackSlot getLast(StackSlot head){
        while(head.next!=null){
            head=head.next;
        }
        return head;
    }

    //获取头结点后的第一个节点
    public static StackSlot getFirst(StackSlot head){
        return head.next;
    }

    //打印链表
    public static void myPrint(StackSlot head,int pageFault){
        head=head.next;
        System.out.print("页面序列-->{ ");
        while(head!=null){
            System.out.print(head.page+" ");
            head=head.next;
        }
        System.out.println("}");
        System.out.println("缺页次数-->"+pageFault);
    }

}


/**
 * 这个栈是由双向链表实现的
 */
class StackSlot {
    //指向前一个节点的地址
    StackSlot pre;
    //页码
    int page;
    //指向下一个节点的地址
    StackSlot next;

    public StackSlot(StackSlot pre, int page, StackSlot next) {
        this.pre = pre;
        this.next = next;
        this.page = page;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值