数据结构02 线性表之顺序表

这篇文章主要总结线性表之顺序表的相关操作,主要分以下几个部分来总结。

1、线性表是什么? 
2、线性表的两种存储结构? 
3、顺序表的存储结构表示?  
4、顺序表的常见操作和代码实现?

 

1、线性表是什么 

(1)线性表是最基本、最简单的一种数据结构。

(2)线性表中元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。

(3)如果是一对多就用树来表示,如果多对多就用网状来表示。

(4)线性表具有以下几个特征:

  ①有且只有一个“首”元素 
  ②有且只有一个“尾”元素 
  ③除“首”元素之外,其余元素都有唯一的前驱元素。 
  ④除“尾”元素之外,其余元素都有唯一的后继元素。

 

2、线性表的两种存储结构

(1)顺序表,即线性表用顺序存储结构保存数据,数据是连续的。这一篇文章总结的就是顺序表 
(2)链表,即线性表用链式存储结构保存数据,数据是不连续的。

 

3、顺序表的存储结构表示

顺序表在内存中的存储结构为连续的存储单元。

 

4、顺序表的常见操作和代码实现 

顺序表主要有以下几个常见操作,我们一般用数组来保存数据

1、初始化

思路:将数组的长度 size 设为0,时间复杂度为O(1)。

2、求顺序表的长度

思路:获取数组的 size 值,时间复杂度为O(1)。

3、插入元素

思路:分两种情况,一种是插入位置在数组的末尾,这种情况的时间复杂度为O(1) 。另一种情况是插入位置在数组的头部,这时候被插入元素的后续元素都要依次向后移动一位,也就是说整个数组都会移动,所以最坏时间复杂度为O(n)。

4、删除元素

思路:同样分两种情况,一种是删除位置在数组的末尾,不用移动任何元素,因此时间复杂度为O(1),另一种情况是删除位置在数组的头部,这时候被删除元素的后续元素都要依次向前移动一位,因此时间复杂度为O(n)。

5、按序号查找元素

思路:因为顺序表的存储地址是连续的,所以第n个元素的地址偏移量公式为:(n-1)*单元存储长度,不用移动任何元素,因此时间复杂度为O(1)。

 

代码实现:

package com.demo;

public class SequenceList {
    // 默认的长度
    final int defaultSize = 10;
    // 最大长度
    int maxSize;
    // 当前长度
    int size;
    // 顺序表对象
    Object[] list;

    /**
     * 1、顺序表的初始化方法
     * 时间复杂度为O(1)
     *
     * @param size
     */
    private void init(int size) {
        this.size = 0;
        maxSize = size;
        list = new Object[size];
    }

    /**
     * 2、求顺序表的长度
     * 时间复杂度为O(1)
     *
     * @return
     */
    public int size() {
        return size;
    }

    /**
     * 3、插入元素
     * 时间复杂度为O(n)
     *
     * @param index
     * @param obj
     * @throws Exception
     */
    public void insert(int index, Object obj) throws Exception {
        // 如果当前顺序表已满,那就不允许插入数据
        if (size == maxSize) {
            throw new Exception("顺序表已满,无法插入!");
        }
        // 插入元素的位置编号是否合法
        if (index < 0 || index > size) {
            throw new Exception("插入元素的位置编号不合法!");
        }
        // 移动元素。 要从后往前操作
        for (int i = size - 1; i >= index; i--) {
            list[i + 1] = list[i];
        }
        list[index] = obj;
        size++;
    }

    /**
     * 4、删除元素
     * 时间复杂度为O(n)
     *
     * @param index
     * @throws Exception
     */
    public void delete(int index) throws Exception {
        // 判断当前顺序表是否为空
        if (size == 0) {
            throw new Exception("顺序表为空,无法删除!");
        }
        // 删除元素的位置编号是否合法
        if (index < 0 || index > size - 1) {
            throw new Exception("删除元素的位置编号不合法!");
        }
        // 移动元素。 要从前往后操作
        for (int i = index; i < size - 1; i++) {
            list[i] = list[i + 1];
        }
        size--;
    }

    /**
     * 5、按序号查找元素
     * 时间复杂度为O(1)
     *
     * @param index
     * @return
     * @throws Exception
     */
    public Object get(int index) throws Exception {
        // 查找元素的位置编号是否合法
        if (index < 0 || index > size - 1) {
            throw new Exception("查找元素的位置编号不合法!");
        }
        return list[index];
    }

}

注意:

插入元素时,移动元素要从后往前操作,否则元素会被覆盖

删除元素时,移动元素要从前往后操作。

 

5、总结

顺序表插入元素和删除元素的时间复杂度为O(n)

顺序表查找一个元素的时间复杂度为O(1) ,因为顺序表可以通过下标直接访问,所以时间复杂度是固定的,和问题规模无关。

 

顺序表的优点:随机访问的速度很快;空间利用率高(存储空间连续分配,不存在浪费)。

顺序表的缺点:大小固定一开始就要固定顺序表的最大长度); 插入和删除元素需要移动大量的数据。

 

欢迎转载,但请保留文章原始出处

本文地址:http://www.cnblogs.com/nnngu/p/8247210.html 

 

posted @ 2018-01-09 04:01  nnngu  阅读(953)  评论(0编辑  收藏  举报