數據結構(七) -- 序列

一,序列

本文將定義并實現一個通用的序列 ADT,從而將向量ADT與列表ADT中的所有方法集成起來——也就是說,這一ADT 將同時支持以秩或位置來訪問其中的元素。因此,這種數據結構將適用于解決更多的實際問題。

數據結構(五) -- 向量

數據結構(六) -- 列表


二,序列ADT(AbstractDataType)

序列ADT將同時支持向量ADT與列表ADT中的所有方法,此外,還支持以下兩個方法——正是借助這兩個方法,我們才得以將秩和位置的概念聯系起來:

操作方法 功能描述
rank2Pos(r) 若0 ≤ r < getSize(),則返回秩為r 的元素所在的位置 ;否則,報錯
輸入:一個(作為秩的)整數
輸出:位置
pos2Rank(p) 若p 是序列中的合法位置,則返回存放于p 處的元素的秩 ;否則,報錯
輸入:一個位置
輸出:(作為秩的)整數

三,基于雙向鏈表實現序列

接口:

package dsa.Sequence;

import other.Position;
import dsa.List.ExceptionPositionInvalid;
import dsa.List.List;
import dsa.Vector.ExceptionBoundaryViolation;
import dsa.Vector.Vector;

/*
 * 序列接口
 */

public interface Sequence extends Vector, List {
    // 若0 <= r < getSize(),則返回秩為r的元素所在的位置;否則,報錯
    public Position rank2Pos(int r) throws ExceptionBoundaryViolation;

    // 若p是序列中的合法位置,則返回存放于p處的元素的秩;否則,報錯
    public int pos2Rank(Position p) throws ExceptionPositionInvalid;
}

實現:

package dsa.Sequence;

import other.Position;
import dsa.Deque.DLNode;
import dsa.List.ExceptionPositionInvalid;
import dsa.List.List_DLNode;
import dsa.Vector.ExceptionBoundaryViolation;

/*
 * 基于雙向鏈表實現序列
 */
public class Sequence_DLNode extends List_DLNode implements Sequence {
    // 檢查秩r是否在[0, n)之間
    protected void checkRank(int r, int n) throws ExceptionBoundaryViolation {
        if (r < 0 || r >= n)
            throw new ExceptionBoundaryViolation("意外:非法的秩" + r + ",應該屬于[0, "
                    + n + ")");
    }

    // 若0 <= r < getSize(),則返回秩為r的元素所在的位置;否則,報錯--O(n)
    public Position rank2Pos(int r) throws ExceptionBoundaryViolation {
        DLNode node;
        checkRank(r, getSize());
        if (r <= getSize() / 2) {// 若秩較小,則
            node = header.getNext();// 從前端開始
            for (int i = 0; i < r; i++)
                node = node.getNext();// 逐一掃描
        } else {// 若秩較大,則
            node = trailer.getPrev();// 從后端開始
            for (int i = 1; i < getSize() - r; i++)
                node = node.getPrev();// 逐一掃描
        }
        return node;
    }

    // 若p是序列中的合法位置,則返回存放于p處的元素的秩;否則,報錯--O(n)
    public int pos2Rank(Position p) throws ExceptionPositionInvalid {
        DLNode node = header.getNext();
        int r = 0;
        while (node != trailer) {
            if (node == p)
                return (r);
            node = node.getNext();
            r++;
        }
        throw new ExceptionPositionInvalid("意外:作為參數的位置不屬于序列");
    }

    // 取秩為r的元素--O(n)
    public Object getAtRank(int r) throws ExceptionBoundaryViolation {
        checkRank(r, getSize());
        return rank2Pos(r).getElem();
    }

    // 將秩為r的元素替換為obj--O(n)
    public Object replaceAtRank(int r, Object obj)
            throws ExceptionBoundaryViolation {
        checkRank(r, getSize());
        return replace(rank2Pos(r), obj);
    }

    // 插入obj,作為秩為r的元素--O(n);返回該元素
    public Object insertAtRank(int r, Object obj)
            throws ExceptionBoundaryViolation {
        checkRank(r, getSize() + 1);
        if (getSize() == r)
            insertLast(obj);
        else
            insertBefore(rank2Pos(r), obj);
        return obj;
    }

    // 刪除秩為r的元素--O(n)
    public Object removeAtRank(int r) throws ExceptionBoundaryViolation {
        checkRank(r, getSize());
        return remove(rank2Pos(r));
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容