数据结构 ---- 线性表

Posted sshhsun-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 ---- 线性表相关的知识,希望对你有一定的参考价值。

线性表的存储结构分为 顺序结构存储 和 链式结构存储

线性表是最常用,最简单的一种数据结构,简而言之,线性表是N个数据元素的有限序列。每个数据元素最多有一个前驱元素,每个元素最多只有一个直接后继元素;只有第一个数据元素没有直接前驱元素,而最后一个元素没有后继元素


在实现线性表的不同存储形式之前,先顶一个接口用于表述线性表的所有操作

package com.sshhsun.list;

public interface LList<T> 
    boolean isEmpty();//判断是否为空
    int length();      //得到长度
    T get(int i);          //返回第i个元素
    void set(int i,T x); //设置第i个元素值x
    void insert(int i,T x); //插入第i个元素值为x,如果超过数组长度则新建一个长度为原来2倍的集合并将原来的值付给新表
    void append(T x); //在线性表最后插入x元素
    T remove(int i);//删除并返回第i个元素
    void removeAll();//清空表
    int search(T key);//返回首次出现的关键字为key的元素位置

顺序表

线性表的实现结构MSeqList类实现LList接口的功能

package com.sshhsun.list;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MSeqList<T> implements LList<T> 
    private Object[] element;
    private int len;

    public MSeqList(int size) 
        this.element = new Object[size];
        this.len = 0;
    

    public MSeqList() // 默认一个长度
        this(64);
    

    @Override //判断是否为空
    public boolean isEmpty() 

        return this.len == 0;
    

    @Override//得到长度
    public int length() 

        return this.len;
    

    @Override //返回第i个元素
    public T get(int i) 

        if (i >= 0 && i < this.len) 
            return (T) this.element[i];
        
        return null;
    

    @Override//设置第i个元素值x
    public void set(int i, T x) 
        if (x == null) 
            return;
        
        if (i >= 0 && i < this.len) 
            this.element[i] = x;
         else 
            throw new IndexOutOfBoundsException(i + "");
        
    

    @Override//插入第i个元素值为x
    public void insert(int i, T x) 
        if (x == null) 
            return;
        
        if (this.len == this.element.length) 
            Object[] temp = this.element;
            this.element = new Object[temp.length * 2];

            for (int j = 0; j < temp.length; j++) 
                this.element[j] = temp[j];
            
        
        if (i < 0 || i > this.len) 
            throw new IndexOutOfBoundsException(i + "");
        
        for (int j = this.len - 1; j >= i; j--) 
            this.element[j + 1] = this.element[j];
        
        this.element[i] = x;
        this.len++;
    

    @Override
    public String toString() 
        StringBuilder str = new StringBuilder("(");
        if (this.len > 0) 
            str.append(this.element[0].toString());
        
        for (int i = 1; i < this.len; i++) 
            str.append("," + this.element[i].toString());
        
        str.append(")");
        return str.toString();
    

    @Override//在线性表最后插入x元素
    public void append(T x) 
        insert(this.len, x);

    

    @Override//删除并返回第i个元素
    public T remove(int i) 
        if (this.len == 0 || i < 0 || i > this.len) 
            return null;
        
        T old = (T) this.element[i];
        for (int j = i; j < this.len - 1; j++) 
            this.element[j] = this.element[j + 1];
        
        this.len--;
        return old;
    

    @Override//清空表
    public void removeAll() 
        for (int i = 0; i < this.len; i++) 
            this.element[i] = null;
        
        this.len = 0;
    

    @Override//返回首次出现的关键字为key的元素位置
    public int search(T key) 
        if (key == null || this.len == 0) 
            return -1;
        
        for (int i = 0; i < this.len; i++) 
            if (this.element[i] == key) 
                return i;
            
        
        return -1;
    


顺序表的操作效率分析

1.顺序表存取任何一个元素的get(),set()方法时间复杂度是 O(1).;
2.对顺序表的插入和删除操作,算法所花费的时间主要用于移动元素。在等概率的情况下,插入一个元素平均需要移动一半的元素,时间复杂度为O(n),删除一个元素的时间复杂度也是O(n).


顺序表解决一个很经典的问题,约瑟夫环的问题
使用顺序表MSeqList解决约瑟夫环的问题:创建一个具有n个元素的顺序表对象List;从第s个元素开始,依次计数,每数到d,就删除对应元素,重复计数并删除元素,直到剩下一个元素。

上代码 !

package com.sshhsun.list;

public class Josephus 

    public Josephus(int number, int start, int distance) 
        MSeqList<String> list = new MSeqList<String>();
        for (int i = 0; i < number; i++) 
            list.append((char) ('A' + i) + "");
        
        System.out.println("约瑟夫环(" + number + "," + start + "," + distance
                + ")");
        System.out.println(list.toString());
        int i = start;
        while (list.length() > 1) 
            i = (i + distance - 1) % list.length(); // 计数按循环规律变化,顺序表可看作是环形结构
            System.out.print("删除" + list.remove(i).toString() + " ,");
            System.out.println(list.toString());
        
        System.out.println("最后的人是" + list.get(0).toString());
    

    public static void main(String[] args) 
        new Josephus(5, 0, 3);
    


结果:

单链表

点击”单链表的实现“

以上是关于数据结构 ---- 线性表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法 线性表一

数据结构与算法四 线性表

线性表之顺序存储结构实现(上)

线性表

线性表

数据结构——线性表