线性表的顺序存储结构

参考资料:《大话数据结构》

线性表(List)的定义

书中给出的定义为:零个或多个数据元素的有限序列。可想象成一串糖葫芦(用一根线可以把所有元素串起来)。

特点:

  1. 元素之间是有序的
  2. 元素的个数是有限个

线性表

当线性表元素的个数n定义为线性表的长度 ,当n=0时,为空表


线性表的顺序存储结构

1. 定义

用一段地址连续的存储单元(数组)依次存储线性表的数据元素。定义一个线性表需要两个元素,即数组的长度和当前线性表中元素的个数(线性表中的n)。数组的长度分配后一般不可变,而线性表中的个数n可以改变,并且n<=数组长度。

int len; //数组长度
int n; //有效元素的个数
int[] arr;
int remove_value; //记录删除的元素的值

2. 获取线性表元素的操作

线性表与数组下标的对应关系为:线性表的第一个元素存储在数组下标为0的位置,第二个元素在下标为1的位置…

在这里插入图片描述
所以,如果我们想要获取线性表第m个元素,等价于获取数组下标为m-1位置上的元素。

3.插入操作

首先,在进行插入操作之前,我们应该判断当前线性表有效元素个数n是否小于数组长度。若小于则可以进行插入操作,否则不可进行插入操作(此时,数组已满,假设数组不能扩容)。

假设现在还可以插入,则判断要插入的位置和数组下标的关系,若想要插入的位置大于数组长度减一,则不能进行插入。

然后进行插入操作。可以想象成排队买票,最后来的人当然排到原来最后一个人的后面,此时为最简单的情况。但现在假设有一个人情况紧急,需要插队(假设和排在第三名位置的人说好了),则从第三名开始之后的人需要依次往后挪一个位置,而且必须是最后一个人先开始挪(想象下,如果你后面的人不动,你怎么往后挪一个位置)。如下图,则是7先动,然后6,一直到3。当3挪动之后(3现在跑到了数组下标为3的位置,即线性表的第四个元素的位置),将要插入的元素的值放到原来3所在的位置(数组下标为2的位置)。

最后将线性表有效元素个数加一。

在这里插入图片描述

if(n == len || pos > len || pos <1) { //如果线性表已满或者要插入的位置pos大于len或插入位置小于1,则不能插入
	
	return false;

}else{
	
	for(int i = n;i > pos - 1; i--){
                arr[i] = arr[i-1]; //从后往前依次移
            }
    
    arr[pos-1] = value;
    n++;  //线性表有效元素个数加一        
}

4. 删除操作

同插入操作一样,在进行删除操作之前,我们应对要删除位置进行判断。如果要删除的位置大于线性表的有效个数n,则不能删除。

若满足上面要求,则首先获取要删除位置的元素,然后从要删除的位置到线性表的最后一个元素,依次往前挪一位。

最后,将线性表有效元素个数减一。
在这里插入图片描述

if(n == 0 || pos < 1 || pos > len){  //线性表为空或者要删除位置小于1或者位置大于数组长度
	return false; 
}else{
	remove_value = arr[pos - 1];
	for(int i = pos;i < n;i++){
		arr[pos-1] = arr[pos]; //从前往后依次移
	}
	n--;
}	

5.线性表顺序存储的优缺点

优点缺点
根据线性表与数组下标的对应关系,可以快速找到要取的元素,因此其查询较快由上面的增删可以看到,对一个位置的增删,需要移动大量的元素,因此增删较慢。此外,由于数组长度固定,当线性表长度变化大时,很难确定数组长度。

Java代码实现

public class Array {

    int len; //数组长度
    int cnt; //有效元素的个数
    int[] arr;
    int remove_value; //记录删除的元素的值

    public Array(int len) {
        cnt = 0;  //有效元素个数刚开始为0,以cnt为下标的位置无值
        this.len = len;
        arr = new int[len];  //初始化数组,长度为len,值都为0
    }


    /*判断数组是否为空*/
    public boolean is_empty() {
        if (cnt == 0)
            return true;
        else
            return false;
    }

    /*输出数组*/
    public void show_Array() throws EmptyException{

        if(is_empty()){
            throw new EmptyException("数组为空,无法输出");
        }else{
            for(int i = 0;i < cnt;i++){
                System.out.println(arr[i]);
            }
        }
    }

    /*判断数组是否满*/
    public boolean is_full(){
        if (cnt == len)
            return true;
        else
            return  false;
    }

    /*数组追加元素*/
    public boolean append_Array (int value) throws FullException {

        if (is_full()) {
            throw new FullException("数组已满,无法追加");
        }else{
            arr[cnt] = value;
            cnt++;
            return true;
        }
    }

    /*在某个特定位置添加元素*/
    public boolean insert_Array(int pos,int value) throws FullException {

        if (is_full()) {
            throw new FullException("数组已满,无法添加");
        }else{
            /*例如要在第三个位置添加,实际上是在下标为2的地方添加,
              从最后一个位置的元素到下标为2的元素,依次向后移一位,
              先移后添加
            */
            for(int i = cnt;i > pos - 1; i--){
                arr[i] = arr[i-1];
            }
            arr[pos - 1] = value;
            cnt++;  //添加后数组元素多一个,故++
            return true;
        }
    }

    /*删除某个位置元素*/
    public boolean delect_Array(int pos)throws EmptyException{

        if(is_empty()) {
            throw new EmptyException("数组为空,无法删除");
        }else if(pos < 1 || cnt < pos){  //若要删除的位置小于1或者大于线性表有效元素的个数,则报错
            return false;
        } else{
            /*同在某个位置添加元素,不同的先将元素删除,再把后面位置的元素依次向前移一位*/
            remove_value = arr[pos - 1];
                for(int i = pos;i < cnt;i++) {
                    arr[i - 1] = arr[i];
                }
         }
        return true;
    }

    /*数组元素倒置,此方法适用于有效元素个数为奇数或偶数*/
    public void inversion_Array(){

        int i = 0;
        int j = cnt - 1;  //最后一个元素的下标为cnt-1
        int t;
        while(i < j){
            t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
            i++;
            j--;
        }
    }

    /*使用冒泡排序对数组进行排序(从小到大)*/
    public void sort_Array(){

        int t;
        for(int i = cnt - 1;i > 0;i--){
            for(int j = 0;j < i;j++){
                if(arr[j] > arr[j+1]){
                    t = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = t;
                }
            }
        }
    }
}

-----------------------------------------------------------------------------------

public class EmptyException extends Exception {

    public EmptyException(String message) {
        super(message);
    }
}

-----------------------------------------------------------------------------------

public class FullException extends Exception{

    public FullException(){
        super();
    }

    public FullException(String message){
        super(message);
    }
}


-----------------------------------------------------------------------------------

public class test {

    public static void main(String[] args) {

        Array a = new Array(5); //数组长度为10,有效元素为0
        try{
            a.append_Array(100);
            a.append_Array(66);
            a.append_Array(88);
            a.insert_Array(2,40);
            a.insert_Array(5,2312);
            a.delect_Array(a.cnt);
            a.show_Array();
        } catch(Exception e){
           e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值