零基础学算法——算法系列(二)(链表、队列、栈)

今天我们来聊聊单节点和双向节点的一些知识吧!
我们在刷算法题的时候,由于力扣等网站已经给我们写好了节点类的定义,但是我们还是要明白它是怎么定义的。
例如,在单向节点中是这样的:

public static class Node{
        public int value;
        public Node next;
        public Node(int data){
            value = data;
        }
    }

在双向节点又是这样定义的:

    public static class DoubleNode{
        public int value;
        public DoubleNode next;
        public DoubleNode last;
        public DoubleNode(int data){
            value = data;
        }
    }

在我们了解节点是如何定义后,让我们来尝试一下如何实现反转链表吧。
在单向链表中,我们可以这样来实现:

    public static Node reverseLinkedList(Node head){
        Node pre = null;
        Node next = null;
        while(head!=null){
            next= head.next;
            head.next=pre;
            pre=head;
            head= next;
        }
        return pre;
    }

在双向链表中这样实现:

    public static DoubleNode reverseDoubleList(DoubleNode head){
        DoubleNode pre = null;
        DoubleNode next = null;
        while (head!=null){
            next = head.next;
            head.next=pre;
            head.last= next;
            pre=head;
            head=next;
        }
        return pre;
    }

在面试中,我们会经常被问到,如何删除链表中的一个数,让我们来看看是如何实现的吧。

//删除一个数
    public static Node removeValue(Node head,int num){
        while (head!=null){
            if(head.value!=num){
                break;
            }
            head=head.next;
        }

        Node pre = head;
        Node cru = head;
        while (cru!=null){
            if(cru.value==num){
                pre.next=cru.next;
            }else {
                pre=cru;
            }
            cru=cru.next;
        }
        return head;
    }

学完了这些,接下来我们来聊聊队列和栈吧!
接下来我们来实现一下队列和栈的实现:

 public static class Node<T>{
        public T value;
        public Node<T> last;
        public Node<T> next;
        public Node(T data){
            value = data;
        }
    }

    public static class DoubleEndsQueue<T>{
        public Node<T> head;
        public Node<T> tail;

        public void addFromHead(T value){
            Node<T> cur = new Node<>(value);
            if(head==null){
                head = cur;
                tail = cur;
            }
            else {
                cur.next = head;
                head.last = cur;
                head = cur;
            }
        }

        public void addFromBottom(T value){
            Node<T> cur = new Node<>(value);
            if(head==null){
                head = cur;
                tail = cur;
            }
            else {
                tail.next = cur;
                cur.last = tail;
                tail=cur;
            }
        }

        public T popFromHead(){
            if(head==null){
                return null;
            }
            Node<T> cur = head;
            if(head==tail){
                head=null;
                tail=null;
            }
            else {
                head=head.next;
                cur.next=null;
                head.last=null;
            }
            return cur.value;
        }

        public T popFromBottom(){
            if(head==null){
                return null;
            }
            Node<T> cur = tail;
            if(head==tail){
                head=null;
                tail=null;
            }
            else {
                tail=tail.last;
                tail.next=null;
                cur.last=null;
            }
            return cur.value;
        }
        public boolean isEmpty(){
            return head==null;
        }
    }

    public static class Mystack<T>{
        private DoubleEndsQueue<T> queue;

        public Mystack(){
            queue = new DoubleEndsQueue<>();
        }
        public void push(T value){
            queue.addFromHead(value);
        }
        public void pop(){
            queue.popFromHead();
        }
        public boolean isEmpty(){
            return queue.isEmpty();
        }
    }

    public static class MyQueue<T>{
        private DoubleEndsQueue<T> queue;

        public MyQueue(){
            queue = new DoubleEndsQueue<>();
        }
        public void push(T value){
            queue.addFromHead(value);
        }
        public void pop(){
            queue.popFromBottom();
        }
        public boolean isEmpty(){
            return queue.isEmpty();
        }
    }

是不是发现原来也不过如此!
好啦!到最后我们来放松一下,学一学递归的简单用法吧!

    public static void main(String[] args) {
        int[] arr = {1,3,5,7,9,2,4,6,8};
        int max = getMax(arr);
        System.out.println(max);
    }
    public static int getMax(int[] arr){
        return process(arr,0,arr.length-1);
    }

    public static int process(int[] arr,int L,int R){
        if(L==R){
            return arr[L];
        }
        int mid = L + ((R-L)>>1);
        int leftMax = process(arr,L,mid);
        int rightMax = process(arr,mid+1,R);
        return Math.max(leftMax,rightMax);
    }

好啦!今天就到这里啦!下期再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值