数据结构

本文深入探讨了数据结构的基础,包括栈的应用、队列的循环实现、链表的特点、递归在数据结构中的作用,以及二叉树的遍历和操作。此外,还介绍了集合Set的典型应用和Map接口的多种实现,是理解数据结构的重要参考资料。
摘要由CSDN通过智能技术生成

一、栈

  1. 栈是一种线性结构
  2. 栈是操作受限的数组,只能从一端添加数据和删除数据
  3. 栈是一种后进先出的数据结构。last in first out lifo

栈的应用

  1. 无处不在的Undo操作(撤销)
  2. 程序调用的系统栈。可以记录一个程序上次终止运行的位置,进栈,进而下次知道从哪里开始执行
  3. 括号匹配-编译器

二、队列

  1. 队列queue是一种线性结构
  2. 队列是操作受限的数组,只能从一端添加元素(队尾),从另一端删除元素(队头)
  3. 先进先出。first in first out FIFO

循环队列

image-20210311155441440

三、链表

优点:真正的动态,不需要考虑容量问题

缺点:丧失了随机访问的能力

image-20210311215050689

/**总结一哈
 * 1.在有虚拟头结点的链表中,dummyHead虚拟头结点默认指向索引0之前
 *      1.获取索引index之前的元素prev
 *      Node prev = dummyHead;
 *      for (int i=0;i<index;i++)
 *          prev=prev.next;
 *      2.获取索引index当前的元素current
 *      Node current = dummyHead.next;
 *      for (int i=0;i<index;i++)
 *          current=current.next;
 * 2.只要方法中有索引index,一定要先判断合法性
 * 3.增删链表之后,不要忘记操作size
 */
public class LinkedList<E> {
   
    /**
     * 结点类
     */
    private class Node{
   
        public E e;
        public Node next;
        public Node(E e, Node next) {
   
            this.e = e;
            this.next = next;
        }
        public Node() {
   
            this(null,null);
        }
        public Node(E e){
   
            this(e,null);
        }
        @Override
        public String toString() {
   
            return e.toString();
        }
    }

    //private Node head;
    //虚拟头结点
    private Node dummyHead;
    private int size;

    public LinkedList() {
   
        dummyHead=new Node(null, null);
        size=0;
    }
    //获取链表个数
    public int getSize(){
   
        return size;
    }
    //链表是否为空
    public boolean isEmpty(){
   
        return size==0;
    }
    //在链表头添加数据e
    public void addFirst(E e){
   
        add(0, e);
        size++;
    }
    //在链表任意索引位置添加元素
    public void add(int index,E e){
   
        //判断索引合法性
        if(index<0||index>size)
            throw  new IllegalArgumentException("index error");
        //prev是索引x的前一个元素,默认指向虚拟头结点,而dummyHead在索引0之前,prev.next执行1次为索引1之前,则遍历index次为索引index之前
        Node prev = dummyHead;
        for (int i=0;i<index;i++)
            prev=prev.next;

//            Node node = new Node(e);
//            node.next=prev.next;
//            prev.next=node;
            prev.next=new Node(e,prev.next);
            size++;
        }
    //在链表末尾添加元素
    public void addLast(E e){
   
        add(size, e);
    }
    //获得某个索引处的元素
    public E get(int index){
   
        //判断索引合法性
        if(index<0||index>=size)
            throw  new IllegalArgumentException("index error");
        Node current = dummyHead.next;
        for (int i=0;i<index;i++)
            current=current.next;
        return current.e;
    }
    //获取第一个元素
    public E getFirst(){
   
        return get(0);
    }
    //获取最后一个元素
    public E getLast(){
   
        return get(size-1);
    }
    //修改指定索引元素
    public void set(int index,E e){
   
        //判断索引合法性
        if(index<0||index>=size)
            throw  new IllegalArgumentException("index error");
        //获取index位置元素
        Node current=dummyHead.next;
        for (int i=0;i<index;i++)
            current=current.next;
        current.e=e;
    }
    //判断是否含有某个元素
    public boolean contains(E e){
   
        Node cur=dummyHead.next;
        while(cur!=null){
   
            if (cur.e.equals(e))
                return true;
            cur=cur.next;
        }
        return false;
    }
    //遍历
    @Override
    public String toString(){
   
        Node cur=dummyHead.next;
        StringBuilder sb = new StringBuilder();
        while(cur!=null){
   
            sb.append(cur+"->");
            cur=cur.next;
        }
        sb.append("null");
        return sb.toString();
    }
    //删除某个位置的元素
    public E remove(int index){
   
        //判断索引合法性
        if(index<0||index>=size)
            throw  new IllegalArgumentException("index error");
        Node prev=dummyHead;
        for (int i=0;i<index;i++)
            prev=prev.next;
        Node delNode=prev.next;
        prev.next=delNode.next;
        delNode.next=null;
        size--;
        return delNode.e;
    }
    public E removeFirst(){
   
        return remove(0);
    }
    public E removeLast(){
   
        return remove(size-1);
    }
}

四、递归

  1. 链表具有天然的递归结构
  2. 二叉树具有天然的递归结构
    1. 每个节点的左子树也是二叉树
    2. 每个节点的右子树也是二叉树

五、树

二叉树

  1. 二叉树不一定是满的

    1. 一个节点也是二叉树,只不过左右节点都为空
    2. NULL 空也是二叉树
  2. 对于满二叉树,如果有h层,则共有有2^h-1个节点

    image-20210317225849432

二分搜索树

BST Binary search tree

  1. 二分搜索树是二叉树
  2. 二分搜索树每个节点的值
    1. 大于其左子树的所有节点的值
    2. 小于其右子树的所有节点的值
  3. 每一棵子树也是二分搜索树
  4. 存储的元素必须有可比较性
//二分搜索树要通过比较节点与节点的大小,以此来判断相对位置
//不是基本类型就不能使用<、>、=进行比较,类型E继承Comparable<E>,实现具有可比性
public class BST<E extends Comparable<E>> {
   
    private class Node{
   
        public E e;
        public Node left,right;
        public Node(E e){
   
            this.e=e;
            left=null;
            right=null;
        }
    }
    private Node root;
    private int size;
    public BST(){
   
        root=null;
        size=0;
    }
}

1. 插入元素_递归

	/*
    //向二分搜索树中插入元素
    public void add(E e){
        if(root==null){
            root=new Node(e);
            size++;
        }
        else
            add(root,e);
    }
    //向以node为根的二叉树中插入元素e,递归算法
    private void add(Node node,E e){
        //递归终止条件
        if (e.equals(node.e))
            return;
        if (e.compareTo(node.e)<0&&node.left==null)
            node.left=new Node(e);
        if (e.compareTo(node.e)>0&&node.right==null)
            node.right=new Node(e);
        if (e.compareTo(node.e)<0)
            add(node.left,e);
        else
            add(node.right,e);
    }
    */
    //对上述递归方法的优化
    //向二分搜索树中插入元素
    public void add(E e){
   
        root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值