使用链表(LinkedList) 二叉搜索树(BST) 实现不重复元素集合(Set)

不重复元素集合Set接口定义如下

public interface Set<E> {

    void add(E e);
    boolean contains(E e);
    void remove(E e);
    int getSize();
    boolean isEmpty();

}

复杂度分析:

在这里插入图片描述

LinkedListSet

import java.util.ArrayList;

public class LinkedListSet <E> implements Set<E>{

    private LinkedList<E> linkedList;
    public LinkedListSet() {
        linkedList = new LinkedList<>();
    }

    @Override
    public void add(E e) {
        if (!linkedList.contains(e)) {
            linkedList.addFirst(e);
        }
    }

    @Override
    public boolean contains(E e) {
        return linkedList.contains(e);
    }

    @Override
    public void remove(E e) {
        linkedList.removeElement(e);
    }

    @Override
    public int getSize() {
        return linkedList.getSize();
    }

    @Override
    public boolean isEmpty() {
        return linkedList.isEmpty();
    }

}

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 (E e) {
            this(e, null);
        }
        public Node () {
            this(null, null);
        }
    }

    private Node dummyHead;
    private int size;

    public LinkedList() {
        dummyHead = new Node();
        size = 0;
    }

    public int getSize() {
        return size;
    }

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

    public void add(E e, int index) {
        if (index < 0 && index >= size)
            throw new IllegalArgumentException("failed");

        Node preNode = dummyHead;
        for (int i = 0; i < index; i++) {
            preNode = preNode.next;
        }
        preNode.next = new Node(e, preNode.next);
        size++;
    }

    public void addFirst(E e) {
        add(e, 0);
    }

    public void addLast(E e) {
        add(e, size);
    }

    public boolean contains(E e) {
        Node curNode = dummyHead.next;
        while (curNode != null) {
            if (curNode.e.equals(e))
                return true;
            curNode = curNode.next;
        }
        return false;
    }

    public E remove(int index) {
        if (index < 0 && index >= size)
            throw new IllegalArgumentException("failed");
        Node preNode = dummyHead;
        for (int i = 0; i < index; i++) {
            preNode = preNode.next;
        }
        Node tempNode = preNode.next;
        preNode.next = tempNode.next;
        tempNode.next = null;
        size--;
        return tempNode.e;
    }

    public E removeFirst() {
        return remove(0);
    }

    public E removeLast() {
        return remove(size-1);
    }

    public void removeElement(E e) {
        Node preNode = dummyHead;
        while (preNode != null) {
            if (preNode.next.e.equals(e))
                break;
            preNode = preNode.next;
        }

        if (preNode.next != null) {
            Node tempNode = preNode.next;
            preNode.next = tempNode.next;
            tempNode.next = null;
            size--;
        }
    }


    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        Node curNode = dummyHead.next;
        while (curNode != null) {
            res.append(curNode.e + "->");
            curNode = curNode.next;
        }
        res.append("Null");
        return res.toString();
    }
}

BSTSet

import java.util.ArrayList;

public class BSTSet <E extends Comparable<E>> implements Set<E> {

    private MyBST<E> myBST;

    public BSTSet() {
        myBST = new MyBST<>();
    }

    @Override
    public void add(E e) {
        myBST.add(e);
    }

    @Override
    public boolean contains(E e) {
        return myBST.contains(e);
    }

    @Override
    public void remove(E e) {
        myBST.remove(e);
    }

    @Override
    public int getSize() {
        return myBST.getSize();
    }

    @Override
    public boolean isEmpty() {
        return myBST.isEmpty();
    }
}

import javax.swing.plaf.InsetsUIResource;

public class MyBST <E extends Comparable<E>> {

    private class Node {
        public E e;
        public Node left, right;
        public Node(E e) {
            this.e = e;
            this.left = null;
            this.right = null;
        }

    }

    private Node root;
    private int size;

    public MyBST() {
        this.root = null;
        this.size = 0;
    }

    public void add(E e) {
        root = add(root, e);
    }

    // 返回插入后的根节点
    private Node add(Node node, E e) {
        if (node == null) {
            size++;
            return new Node(e);
        }
        if (e.compareTo(node.e) < 0) {
            node.left = add(node.left, e);
        } else if (e.compareTo(node.e) > 0) {
            node.right = add(node.right, e);
        }
        return node;
    }

    // 典型的添加错误
//    private void add(Node node, E e) {
//        if (node == null) {
//            size++;
//            下面这条语句仅仅让node指向了一个新的地址 但是并没有把这个节点与二叉树连接起来
//            node = new Node(e);
//            return;
//        }
//        if (e.compareTo(node.e) < 0)
//            add(node.left, e);
//        if (e.compareTo(node.e) > 0)
//            add(node.right, e);
//    }

    // preOrder 前序遍历
    public void preOrder() {
        preOrder(root);
        System.out.println("Null");
    }

    private void preOrder(Node node) {
        if (node == null)
            return;
        System.out.print(node.e + "->");
        preOrder(node.left);
        preOrder(node.right);
    }

    // inOrder 中序遍历
    public void inOrder() {
        inOrder(root);
        System.out.println("Null");
    }

    private void inOrder(Node node) {
        if (node == null)
            return;
        inOrder(node.left);
        System.out.print(node.e + "->");
        inOrder(node.right);
    }

    // postOrder 后续遍历
    public void postOrder() {
        postOrder(root);
        System.out.println("Null");
    }

    private void postOrder(Node node) {
        if (node == null)
            return;
        postOrder(node.left);
        postOrder(node.right);
        System.out.print(node.e + "->");
    }

    // 返回当前以node为根的二叉树的最小值
    public E minimum() {
        if (size == 0)
            throw new IllegalArgumentException("BST is empty");
        return minimum(root).e;
    }

    private Node minimum(Node node) {
        if (node.left == null) {
            return node;
        }
        return minimum(node.left);
    }

    public void removeMin() {
        removeMin(root);
    }

    private Node removeMin(Node node) {
        if (node.left == null) {
            size--;
            Node rightNode = node.right;
            node.right = null;
            return rightNode;
        }
        node.left = removeMin(node.left);
        return node;
    }

    // 返回已node为根的二叉树的最大值
    public E maximum() {
        if (size == 0)
            throw  new IllegalArgumentException("BST is empty");
        return maximum(root).e;
    }

    private Node maximum(Node node) {
        if (node.right == null)
            return node;
        return maximum(node.right);
    }

    // 删除最大元素
    public E removeMax() {
        E e = maximum();
        root = removeMax(root);
        return e;
    }

    private Node removeMax(Node node) {
        if (node.right == null) {
            size--;
            Node leftNode = node.left;
            node.left = null;
            return leftNode;
        }
        node.right = removeMax(node.right);
        return node;
    }

    // 删除任意元素
    public void remove(E e) {
        root = remove(root, e);
    }

    private Node remove(Node node, E e) {

        if (node == null)
            return null;

        if (e.compareTo(node.e) == 0) {
            if (node.left == null) {
                size--;
                Node rightNode = node.right;
                node.right = null;
                return rightNode;
            } else if (node.right == null) {
                size--;
                Node leftNode = node.left;
                node.left = null;
                return leftNode;
            } else {
                Node precursor = maximum(node.left);
                precursor.left = removeMax(node.left);
                precursor.right = node.right;
                node.left = node.left = null;
                return precursor;
            }
        } else if (e.compareTo(node.e) < 0) {
            node.left = remove(node.left, e);
        } else {
            node.right = remove(node.right, e);
        }
        return node;
    }

    public boolean contains(E e) {
        return contains(root, e);
    }

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

    private boolean contains(Node node, E e) {
        if (node == null) {
            return false;
        }
        if (e.compareTo(node.e) == 0) {
            return true;
        }
        if (e.compareTo(node.e) < 0) {
            return contains(node.left, e);
        } else {
            return contains(node.right, e);
        }
    }

    public int getSize() {
        return this.size;
    }

}

### 回答1: Java语言使用二叉搜索树BST)为文稿建立单词索引表的算法设计如下: 1. 首先,对文稿中的每个单词进行分割,然后将它们存储在一个字符串数组中。 2. 创建一个二叉搜索树,其中每个节点都存储一个单词。 3. 对于每个单词,将其作为一个节点插入到二叉搜索树中。如果树中已经存在该单词,则将该单词的出现次数加一。 4. 遍历二叉搜索树,将单词及其出现的位置记录在单词索引表中。 5. 最后,可以使用单词索引表对文稿进行快速查询和分析。 使用二叉搜索树进行单词索引的优点是,插入和查询的时间复杂度都是O(log n),因此构建单词索引表非常高效。 ### 回答2: BST(Binary Search Tree)是一种二叉搜索树的数据结构,可以用于构建单词索引表。 首先,我们需要定义一个单词索引表的数据结构。可以使用一个包含单词和与之相对应的出现次数的键值对来表示每个单词的索引项。 接下来,我们依次读取文稿中的单词,并按照以下规则进行处理: 1. 如果单词已存在于索引表中,则将该单词对应的出现次数加1。 2. 如果单词不存在于索引表中,则创建新的索引项,并将该单词插入到二叉搜索树中。 算法的具体步骤如下: 1. 创建一个空的二叉搜索树BST)作为索引表。 2. 读取文稿中的每个单词。 3. 对于每个单词,先查找它在索引表中是否存在。 a. 如果存在,则将对应的出现次数加1。 b. 如果不存在,则创建一个新的索引项,并插入到二叉搜索树中。 4. 重复步骤2和3,直到文稿中的所有单词都被处理。 5. 遍历二叉搜索树,输出单词索引表。 利用BST的特性,可以在很短的时间内找到、插入和更新单词的索引项。在最坏情况下,算法的时间复杂度为O(nlogn),其中n是文稿中的单词数量。 需要注意的是,BST对于有序数据的插入、查找和删除等操作的时间复杂度退化为O(n),因此在插入单词之前,我们可以对索引表进行平衡操作(如红黑树的调整),以确保树的平衡性,提高操作效率。 ### 回答3: BST(Binary Search Tree)是一种二叉搜索树,可以使用它来建立文稿的单词索引表。下面是使用Java语言实现该算法的设计。 首先,我们需要定义一个节点类,用于表示BST的节点。节点包含两个成员变量:一个单词和一个链表,用于存储该单词在文稿中出现的位置。 ```java class Node { String word; LinkedList<Integer> positions; Node left; Node right; public Node(String word, int position) { this.word = word; positions = new LinkedList<>(); positions.add(position); left = null; right = null; } } ``` 接下来,我们创建一个BST的类,用于构建单词索引表。类中包含一个根节点和相应的操作方法。 ```java class BST { Node root; public BST() { root = null; } public void insert(String word, int position) { root = insertNode(root, word, position); } private Node insertNode(Node root, String word, int position) { if (root == null) { return new Node(word, position); } if (word.compareTo(root.word) < 0) { root.left = insertNode(root.left, word, position); } else if (word.compareTo(root.word) > 0) { root.right = insertNode(root.right, word, position); } else { // 单词已存在,更新位置链表 root.positions.add(position); } return root; } public void printIndexTable() { printInorder(root); } private void printInorder(Node root) { if (root != null) { printInorder(root.left); System.out.print(root.word + ": "); for (int position : root.positions) { System.out.print(position + " "); } System.out.println(); printInorder(root.right); } } } ``` 在主程序中,我们可以使用BST类来构建单词索引表。 ```java public class Main { public static void main(String[] args) { BST indexTable = new BST(); String document = "This is a sample text document. It contains some words for indexing."; String[] words = document.toLowerCase().split(" "); for (int i = 0; i < words.length; i++) { indexTable.insert(words[i], i+1); } indexTable.printIndexTable(); } } ``` 以上算法设计中,首先将文稿中的单词转换为小写并拆分为数组。然后依次将单词插入到BST中,如果单词已存在,则更新位置链表。最后,通过中序遍历BST输出单词索引表。 这个算法的时间复杂度为O(nlogn),其中n是文稿中的单词数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值