1. 程式人生 > >java資料結構之手動實現單鏈表

java資料結構之手動實現單鏈表

package com.example.demo;

// 1、定義要儲存物件的類:
class Phone {// 此類提供要儲存的資料
    private String brand;
    private double price;

    public Phone() {
    }

    public Phone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public boolean equals(Object obj) {// 物件比較
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Phone other = (Phone) obj;
        if (brand == null) {
            if (other.brand != null)
                return false;
        } else if (!brand.equals(other.brand))
            return false;
        if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
            return false;
        return true;
    }

    //重寫hashCode
    @Override
    public int hashCode() {
        return Integer.valueOf(brand.hashCode()+price*63+"");
    }

    @Override
    public String toString() {
        return "brand = " + this.brand + ", price = " + this.price;
    }
}

//2、定義連結串列的操作標準:
interface ILink {// 定義連結串列操作標準

    void add(Object obj);// 向連結串列中儲存資料

    int size();// 取得連結串列的長度

    Object get(int index);// 根據索引取得對應的資料

    boolean isEmpty();// 判斷連結串列是否為空

    boolean contains(Object obj);// 判斷某一物件是否存在

    void set(int index, Object obj);// 根據索引設定資料

    void remove(Object obj);// 刪除資料

    void clean();// 清空連結串列

    Object[] toArray();// 取得連結串列中的所有資料
}

//3、連結串列的具體實現:
class LinkImpl implements ILink {
    // ****************************************************
    private Node root;// 根節點
    private int count;// 統計連結串列中的元素個數
    private int foot;// 連結串列元素的下角標
    private Object[] retArray;// 用於接收返回連結串列中的所有資料

    private class Node {// 私有內部類,為外部類服務實現資料的增加等一系列的操作
        private Object data;// 可以儲存任意型別的資料
        private Node next;// 指向下一個節點

        public Node(Object data) {// 資料封裝
            this.data = data;
        }

        public void addNode(Node newNode) {
            if (this.next == null) {
                this.next = newNode;
            } else {
                this.next.addNode(newNode);
            }
        }

        public Object getNode(int index) {
            if (LinkImpl.this.foot++ == index) {
                return this.data;
            } else {
                return this.next.getNode(index);
            }
        }

        public boolean containsNode(Object obj) {// 需要物件比較
            if (this.data.equals(obj)) {
                return true;
            } else {
                if (this.next != null) {
                    return this.next.containsNode(obj);
                }
                return false;
            }
        }

        public void setNode(int index, Object obj) {
            if (LinkImpl.this.foot++ == index) {
                this.data = obj;
            } else {
                this.next.setNode(index, obj);
            }
        }

        public void removeNode(Node previous, Object obj) {// 需要物件比較
            if (this.data.equals(obj)) {
                previous.next = this.next;
            } else {
                this.next.removeNode(this, obj);
            }
        }

        public void toArrayNode() {
            LinkImpl.this.retArray[foot++] = this.data;
            if (this.next != null) {
                this.next.toArrayNode();
            }
        }
    }



    @Override
    public void add(Object obj) {
        if (obj == null) {// 要儲存的資料為空,則結束呼叫
            return;
        }
        Node newNode = new Node(obj);// 封裝資料為一節點
        if (this.root == null) {
            this.root = newNode;
        } else {
            this.root.addNode(newNode);
        }
        this.count++;// 資料增加成功,count 自增
    }

    @Override
    public int size() {
        return this.count;
    }

    @Override
    public Object get(int index) {
        if (this.isEmpty()) {// 連結串列為空
            return null;
        }
        if (index >= this.count) {
            return null;
        }
        this.foot = 0;// 保證資料是從第一個開始遍歷
        return this.root.getNode(index);
    }

    @Override
    public boolean isEmpty() {
        return this.count == 0 && this.root == null;// 根節點不存在或者連結串列中的元素個數為0,表示連結串列為空連結串列
    }

    @Override
    public boolean contains(Object obj) {
        if (this.isEmpty()) {
            return false;
        }
        return this.root.containsNode(obj);
    }

    @Override
    public void set(int index, Object obj) {
        if (this.isEmpty()) {
            return;
        }
        if (index >= this.count) {
            return;
        }
        this.foot = 0;
        this.root.setNode(index, obj);
    }

    @Override
    public void remove(Object obj) {
        if (!this.contains(obj)) {
            return;
        }
        if (this.root.data.equals(obj)) {
            this.root = this.root.next;
        } else {
            this.root.next.removeNode(this.root, obj);
        }
        this.count--;// 資料刪除成功,count 自減
    }

    @Override
    public void clean() {
        this.count = 0;
        this.root = null;
    }

    @Override
    public Object[] toArray() {
        if (this.isEmpty()) {
            return null;
        }
        this.foot = 0;
        this.retArray = new Object[this.count];
        this.root.toArrayNode();
        return this.retArray;
    }
}

//4、編寫測試資料:
public class TestDemo {
    public static void main(String[] args) {
        ILink all = new LinkImpl();// 通過向上轉型例項化連結串列
        System.out.println(all.size());
        System.out.println(all.isEmpty());
        all.add(new Phone("大米手機", 1999.0));
        all.add(new Phone("白米手機", 999.0));
        all.add(new Phone("黑族手機", 1999.0));
        System.out.println(all.isEmpty());
        System.out.println(all.size());
        System.out.println(all.get(1));
        System.out.println(all.contains(new Phone("黑族手機", 1999.0)));
        all.set(2, new Phone("白族手機", 899.0));
        System.out.println(all.get(2));
        all.remove(new Phone("白米手機", 999.0));
        System.out.println(all.size());
        Object obj[] = all.toArray();
        for (int x = 0; x < obj.length; x++) {
            System.out.println(obj[x]);
        }
    }
}