数据结构之线性表

线性表是最基本的一种数据结构,它是一种线性结构,是一种含有n>=0个结点的序列,其中开始结点没有前驱,终端结点没有后继,其他结点有且只有一个前驱和后继。

特征:集合中必然存在且只有一个开始结点和终端结点。其他结点均有一个前驱和后继

下面先实现线性表接口IList,其中定义了对该表的许多操作:

package ilist;

public interface IList<E> 
{
	public void clear();//清空
	public boolean isEmpty();//判空
	public int length();//求表长
	public E get(int i)throws Exception;//取出某一个元素
	public int indexOf(E x)throws Exception;//某一元素出现的第一个位置
	public void insert(int i,E x)throws Exception;//在位置i插入一个新的元素
	public void remove(int i)throws Exception;//删除位置号为i的数据元素
	public void display();//打印表的数据元素
}
实现该线性表的接口有2种形式: 顺序表和链表,顺序表在逻辑结构是相邻、存储结构也是相邻的,一般用连续的存储单元来存储数据,属于静态表,其优点有便于随机存取

元素,但是在删除和插入数据时,需要移动大量的元素的位置。而链表是属于动态表,用不连续的存储单元来存储数据,优点是利于插入和删除,但是不方便访问数据。

下面是SqList的代码实现:

package SqList;

public class SqList<E> implements IList<E> {

    protected E[] listElem;//存储数据
    protected int curlen;

    public SqList() {
        curlen = 0;
        listElem = null;
    }

    public SqList(int maxsize) {
        curlen = 0;
        listElem = (E[]) new Object[maxsize];
    }

    //清空操作
    public void clear() {
        curlen = 0;

    }

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

    public int length() {

        return curlen;

    }

    @Override
    public E get(int i) throws Exception {

        if (i < 0 || i > curlen - 1) {
            throw new Exception("第" + i + "元素不存在");
        }

        return listElem[i];

    }

    @Override
    public void insert(int i, E x) throws Exception {
        if (curlen == listElem.length) {
            throw new Exception("循序表已经满了");
        }
        if (i < 0 || i > curlen) {
            throw new Exception("插入位置不合法");
        }

        for (int j = curlen; j > i; j--) {
            listElem[j] = listElem[j - 1];

        }
        listElem[i] = x;
        curlen++;

    }

    @Override
    public void remove(int i) throws Exception {

        if (this.isEmpty()) {
            throw new Exception("循序表已经空了");
        }
        if (i < 0 || i >= curlen) {
            throw new Exception("删除位置不合法");
        }
        for (int j = i; j < curlen - 1; j++) {
            listElem[j] = listElem[j + 1];
        }
        curlen--;

    }

    public int indexOf(E x) {
        int j = 0;
        while (j < curlen && !listElem[j].equals(x)) {
            j++;
        }
        if (j < curlen) {
            return j;
        } else {
            return -1;
        }

    }

    @Override
    public void display() {

        for (int j = 0; j < curlen; j++) {
            System.out.println(listElem[j]);
        }

    }

}

链表的实现方法是,每一个结点由2部分组成:数据域和指针域,数据域用于存储数据元素,而指针域用来存储它下一个结点的引用值(Node);除此之外,链表需要一个头结点,其指针域指向头结点,而数据域为空,结点类描述如下:

public class Node<E> {

    private E data;//存储数据元素
    private Node next;//存储下一个结点的引用值

    public Node() {
        data = null;
        next = null;
    }

    public Node(E data) {
        this.data = data;
        next = null;

    }

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

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

}

链表代码实现如下:

import SqList.IList;

public class LinkList<E> implements IList<E> {

    private Node<E> head;
    private int curlen;

    public LinkList() {
        head = new Node<E>();
        curlen = 0;
    }

    public Node<E> getHead() {
        return head;
    }

    @Override
    public void clear() {

        head.setNext(null);
        curlen = 0;

    }

    @Override
    public boolean isEmpty() {

        return head.getNext() == null;

    }

    @Override
    public int length() {

        return curlen;

    }

    @Override
    public E get(int i) throws Exception {

        if (i < 0 || i > curlen - 1) {
            throw new Exception("");
        }
        Node<E> p = head.getNext();
        int j = 0;
        while (p != null && j < i) {
            p = p.getNext();
            ++j;
        }
        return p.getData();
    }

    @Override
    public void insert(int i, E x) throws Exception {

        if (i < 0 || i > curlen) {
            throw new Exception("dfghj");
        }
        Node<E> s = new Node<E>(x);
        Node<E> p = head;
        int j = -1;
        while (p != null && j < i - 1) {
            p = p.getNext();
            ++j;
        }

        s.setNext(p.getNext());
        p.setNext(s);
        curlen++;
    }

    @Override
    public void remove(int i) throws Exception {

        if (this.isEmpty()) {
            throw new Exception("链表已空");
        }
        if (i < 0 || i > curlen - 1) {
            throw new Exception("删除位置不合法");
        }
        Node<E> p = head;
        int j = -1;
        while (p.getNext() != null && j < i - 1) {
            p = p.getNext();
            ++j;
        }
        p.setNext(p.getNext().getNext());
        curlen--;

    }

    @Override
    public int indexOf(E x) {

        Node<E> p = head.getNext();
        int j = 0;
        while (p != null && !p.getData().equals(x)) {
            p = p.getNext();
            ++j;
        }
        if (p != null) {
            return j;
        } else {
            return -1;
        }

    }

    @Override
    public void display() {

        Node<E> node = head.getNext();
        while (node != null) {
            System.out.println(node.getData());
            node = node.getNext();    // 取下一个结点

        }

    }

}


对于线性表的介绍第一波就到此介绍,后面讲介绍线性表的应用。在实际应用中,线性表都是实际上是以栈、队列、字符串和数组等特殊线性表使用的。后面将会一一介绍。





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值