数据结构(三)链接存储实现集合Set

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/real_ilin/article/details/80032581

一、链接存储

集合的顺序存储是通过数组实现的,而集合的链接存储是通过存储结点之间的链接实现的,链接形成的结果是一个链接表。构成链接表的每个结点由值域指针域构成,值域存储数据,指针域是下一个结点的引用,以此来指向下一个结点。这样一个结点链接另一个结点构成的是一个单链表。第一结点称作表头结点,最后一个结点称作表尾结点。前面的结点称作前驱结点,指针指向的结点称作后继结点。

二、链表实现集合

  • Node
package set;

/**
 * 链表存储的结点由值域和指针域组成
 */
public class Node {
    //值域
    Object element;
    //指针域
    Node next;

    public Node(Node next) {
        this.next = next;
    }

    public Node(Object element, Node next) {
        this.element = element;
        this.next = next;
    }
}  
  • LinkedSet
    首先有一个表头指针,用head表示,是一个Node类型的数据,其值是附加表头结点的引用。head.next表示是链表的第一个元素的引用。有一个长度用length表示,初始化的LinkedSet的length为0,说明附加表头是不占元素数量的。
package set;

public class LinkedSet implements Set {
    //表头指针
    private Node head;
    //长度
    private int length;

    public LinkedSet() {
        length = 0;
        //表头指针指向附加头结点,附加头结点的指针域为null表示为空链表
        head = new Node(null);
    }

    /**
     * 1.操作表头指针遍历链表,如果链表中有相同的数据则返回false
     * 2.如果链表中没有,此时表头指针已经是表尾结点了。
     * 3.在链表的尾部插入元素
     *
     * @param obj
     * @return
     */
    @Override
    public boolean add(Object obj) {
        Node p = head;
        //遍历链表,把p不断往后移动,直到最后一个元素,操作的是表头指针
        while (p.next != null) {
            if (obj.equals(p.next.element)) return false;
            //把p从head变为附加头结点
            p = p.next;
        }
        //如果p.next=null表明是表尾结点,在链表的结尾插入元素
        p.next = new Node(obj, null);
        length++;
        return true;
    }

    @Override
    public boolean remove(Object obj) {
        Node p = head;
        while (p.next != null) {
            //如果有元素有Obj相同,跳出循环
            if (obj.equals(p.next.element)) break;
            p = p.next;
        }
        //p是附加头结点,p.next是要删掉的元素
        if (p.next != null) {
            p.next = p.next.next;
            length--;
            return true;
        }
        return false;
    }

    @Override
    public boolean contains(Object obj) {
        Node p = head;
        while (p.next != null) {
            if (obj.equals(p.next.element)) return true;
            p = p.next;
        }
        return false;
    }

    @Override
    public Object value(int index) {

        if (index > length - 1 || index < 0) {
            throw new IllegalArgumentException("Wrong arg, please input a correct arg");
        }

        Node p = head;
        int counter = 0;
        while (p.next != null) {
            if (index == counter) return p.next.element;
            counter++;
            p = p.next;
        }
        return null;
    }

    @Override
    public Object find(Object obj) {

        Node p = head;
        while (p.next != null) {
            if (obj.equals(p.next.element)) return p.next.element;
            p = p.next;
        }

        return null;
    }

    @Override
    public int size() {
        return length;
    }

    @Override
    public boolean isEmpty() {
        return length == 0;
    }

    @Override
    public void outputAll() {
        Node p = head;
        while (p.next != null) {
            System.out.println(p.next.element);
            p = p.next;
        }
    }

    @Override
    public Set union(Set set) {
        LinkedSet destSet = new LinkedSet();
        LinkedSet linkedSet = (LinkedSet) set;
        Node p = head;
        while (p.next != null) {
            destSet.add(p.next.element);
            p = p.next;
        }

        Node q = linkedSet.head;
        while (q.next != null) {
            destSet.add(q.next.element);
            q = q.next;
        }
        return destSet;
    }

    @Override
    public Set intersection(Set set) {
        LinkedSet tempSet = new LinkedSet();
        LinkedSet linkedSet = (LinkedSet) set;
        Node p = head;
        while (p.next != null) {
            if (linkedSet.contains(p.next.element)) tempSet.add(p.next.element);
            p = p.next;
        }
        return tempSet;
    }

    @Override
    public void clear() {
        length = 0;
        head.next = null;
    }

    @Override
    public String toString() {
        int iMax = length - 1;
        if (iMax == -1) return "[]";
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        Node p = head;
        for (int i = 0; ; i++) {
            sb.append(String.valueOf(p.next.element));
            //如果是最后一个的话
            if (i == iMax) return sb.append("]").toString();
            sb.append(", ");
            p = p.next;
        }
    }
}
  • 测试类
package setTest;

import set.LinkedSet;

public class LinkedSetTest {
    public static void main(String[] args) {
        LinkedSet linkedSet = new LinkedSet();
        linkedSet.add("ok");
        linkedSet.add("hello");
        linkedSet.add("world");
        System.out.println(linkedSet);

        linkedSet.remove("ok");
        System.out.println(linkedSet);

        System.out.println(linkedSet.contains("ok"));

        System.out.println(linkedSet.value(1));

        System.out.println(linkedSet.find("hello"));

        System.out.println("=====================");
        System.out.println(linkedSet);

        LinkedSet uSet = new LinkedSet();
        uSet.add("a");
        uSet.add("b");
        uSet.add("hello");
        System.out.println(linkedSet.union(uSet));

        System.out.println(linkedSet);
        System.out.println(uSet);
        System.out.println(linkedSet.intersection(uSet));
    }
}

猜你喜欢

转载自blog.csdn.net/real_ilin/article/details/80032581