算法通关村第四关 - 栈、队列和Hash:栈的实现

基础知识(青铜挑战)

  • 认识栈这个数据结构:先进先出

  • 常用的栈操作有:

    • push(E e):入栈

    • peek():弹出栈顶元素

    • pop():出栈

    • empty():判断栈是否为空

  • 我们尝试手动创建一个栈数据结构,并实现它的基础功能:
基于数组实现栈
/**
 * 基于数组实现
 * @param <T>
 */
class Mystack2<T> {
    // 内部数组
    private Object[] stack;
    // 栈顶
    private int top;
​
    // 初始化
    public Mystack2(int size) {
        stack = new Object[size];
    }
​
    // 入栈
    public void push(T t) {
        // todo 检查数组是否已满,扩容
        this.expandCapacity(top + 1);
        this.stack[top] = t;
        top++;
    }
​
    // 弹出栈顶元素
    public T peek() {
        T t = null;
        if (!this.empty())
            t = (T) this.stack[top - 1];
        return t;
    }
​
    // 出栈
    public T pop() {
        T t = this.peek();
​
        this.stack[top - 1] = null;
        top--;
​
        return t;
    }
​
    // 判空
    public boolean empty() {
        return this.top <= 0;
    }
​
    // 校验数组大小,判断是否需要扩容
    public void expandCapacity(int size) {
        int capacity = this.stack.length;
        if (size > capacity) {
            // 扩容1.5倍
            capacity = capacity * 3 / 2 + 1;
            this.stack = Arrays.copyOf(stack, capacity);
        }
    }
​
    public static void main(String[] args) {
        Mystack2<String> stack = new Mystack2<>(10);
        System.out.println(stack.peek());
        System.out.println(stack.empty());
        stack.push("java");
        stack.push("is");
        stack.push("beautiful");
        stack.push("language");
        System.out.println(stack.pop());
        System.out.println(stack.empty());
        System.out.println(stack.peek());
    }
}
基于链表实现栈
/**
 * 基于链表实现
 *
 * @param <T>
 */
class ListStack2<T> {
    // 栈顶节点
    private Node head;
​
    // 入栈
    public void push(T t) {
        if (t == null) {
            throw new NullPointerException("参数不能为空");
        }
​
        if (head == null) {
            head = new Node(t);
            head.next = null;
        } else {
            Node node = new Node(t);
            node.next = head;
        }
    }
​
    // 弹出栈顶元素
    public T peek() {
        return head.t;
    }
​
    // 出栈
    public T pop() {
        head = head.next;
        return head.t;
    }
​
    // 判断栈是否为空
    public boolean empty() {
        return head == null;
    }
​
    // 节点结构
    class Node {
        private T t;
        private Node next;
​
        public Node(T t) {
            this.t = t;
        }
    }
}
Hash
  • Hash,又称散列,将任意长度的输入,通过散列算法,转换为固定长度的输出

  • 映射、扩容机制

  • 碰撞处理(Hash冲突)

    • 开放寻址法

    • 链地址法

    • 再哈希法(布隆过滤)

    • 建立公共溢出区

队列
  • 特点:先进先出(2023/09/03午)
  • 用链表实现队列

  • 具体代码如下:

public class LinkQueue {
    private Node front;
    private Node rear;
    private int size;
​
    public LinkQueue() {
        this.front = new Node(0);
        this.rear = new Node(0);
    }
​
    /**
     * 入队
     */
    public void push(int value) {
        // 尾插法
        Node newNode = new Node(value);
        Node temp = front;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = newNode;
        rear = newNode;
        size++;
    }
​
    /**
     * 出队
     */
    public int pull() {
        // 头删法
        if (front.next == null) {
            System.out.println("队列已空");
        }
        Node firstNode = front.next;
        front.next = firstNode.next;
        size--;
        return firstNode.data;
    }
​
    /**
     * 遍历队列
     */
    public void traverse() {
        Node temp = front.next;
        while (temp != null) {
            System.out.print(temp.data + "\t");
            temp = temp.next;
        }
    }
​
    static class Node {
        public int data;
        public Node next;
​
        public Node(int data) {
            this.data = data;
        }
    }
​
    //测试main方法
    public static void main(String[] args) {
        LinkQueue linkQueue = new LinkQueue();
        linkQueue.push(1);
        linkQueue.push(2);
        linkQueue.push(3);
        System.out.println("第一个出队的元素为:" + linkQueue.pull());
        System.out.println("队列中的元素为:");
        linkQueue.traverse();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CFB-HASH算法和CBC-Hash算法都是密码学中的哈希函数算法,用于将任意长度的数据转化为固定长度的哈希值。它们的相似之处在于都使用了反馈模式(Feedback Mode)进行数据处理。 然而,它们在具体的实现和运作方式上存在一些区别。 1. 工作模式: - CFB-HASH:CFB-HASH(Cipher Feedback Hash)是一种基于块密码的哈希函数,使用块密码算法加密器作为其内部的核心函数。它通过将前一个输出块作为下一个输入块的密钥,将明文分块加密并与输入数据异或,生成哈希值。 - CBC-Hash:CBC-Hash(Cipher Block Chaining Hash)也是一种基于块密码的哈希函数,但它使用块密码算法加密器作为其内部的加密函数。它通过将前一个输出块与当前输入块进行异或操作,并将结果作为下一个输入块的数据,生成哈希值。 2. 安全性: - CFB-HASH:CFB-HASH算法由于使用了反馈模式,对于同一个输入数据生成的哈希值是不确定的。这种不确定性可能导致在某些情况下出现碰撞(collision)问题,从而降低了安全性。 - CBC-Hash:CBC-Hash算法通过使用块密码算法的加密过程,可以提供更好的安全性。由于输入数据的每个块都受到前一个块的影响,使得哈希值更加随机化,减少了碰撞的概率。 总体而言,CFB-HASH和CBC-Hash算法实现方式上存在一些差异,主要体现在加密器的使用和输出结果的确定性上。在选择使用其中一种算法时,需要根据具体应用场景和安全性需求来做出合适的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值