线性表的插入和删除(Java版)

1、线性表的定义:

  (1)、线性表是一种可以在任意位置插入和删除数据元素操作、由n(n≥0)个相同类型数据元素a0, a1,…, an-1组成的线性结构。除了第一个元素没有前驱元素和最后一个元素没有后继元素外,其他元素有且只有一个直接元素和一个直接后继元素。
  (2)、在逻辑上,线性结构的特点是数据元素之间存在着“一对一”的逻辑关系,这种关系的数据结构通常称为线性结构;同样,任何一个线性结构都可以用线性表表示出来,只需要按照他们逻辑的顺序将它们进行排列即可。

2、线性表抽象数据类型(Java接口)

	package com.gx.doem.linear;
	//线性表接口List,描述线性表抽象数据类型,泛型参数T表示数据元素的数据类型
	public interface List<T> {
	  //线性表判空操作isEmpty():判断线性表是否为空,若为空,则返回true;否则,返回为false。
	    boolean isEmpty();
	    //获取长度
    int length();
	   //返回第i(i≥0)个元素
	    T get(int i);
	  // 设置第i个元素值为x
	    void set(int i, T x);
	  //插入操作insert(i,x):在线性表的第i个数据元素之前插入一个值为x的数据元素。其中i的取值范围为0≤i≤length()。当i=0时,在表头插入x;当i=length()时,在表尾插入x。
	    void insert(int i, T x);
	   //在线性表最后插入x元素
	    void append(T x);
	   //删除第i个元素并返回被删除对象
	    T remove(int i);
   // 删除线性表所有元素
	    void removeAll();
	   // 查找,返回首次出现的关键字为key元素
	    T search(T key);
	}

3、线性表的顺序表示和实现

  (1)、顺序表的存储结构:实现顺序存储结构的方法是使用数组。数组把线性表的数据元素存储在一块连续地址空间的内存单元中,这样线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。数据元素间的逻辑上的前驱、后继逻辑关系就表现在数据元素的存储单元的物理前后位置上。
  (2)、顺序表的存储结构如下图所示:
在这里插入图片描述

其中a0,a1,a2等表示顺序表中存储的数据元素,ListArray表示顺序表存储数据元素的数组,maxSize表示存储顺序表的数组的最大存储单位个数,size表示顺序表当前存储的数据元素个数。
  (3)、顺表的特点:
优点:1、在线性表中逻辑上相邻的数据元素,在物理存储上也是相邻的。
    2、便于随机存储。
缺点:1、存储密度高,但要预先分配“足够应用”的存储空间,这可能会造成存储空间的浪费。
    2、不便于插入和删除操作,这是因为在顺序表上进行的插入和删除操作会引起大量数据元素的移动。
  (4)、顺序表的操作实现(实现线性表的接口)

	package com.gx.doem.linear;
	
	  public class SeqList<T> implements LList<T> {
	  //对象数组,保护成员
	    protected Object[] element;
	  //顺序表长度,记载元素个数
	    protected int len;
	  // 默认构造方法,创建默认容量的空表
	    public SeqList() {
	        this(64);
	    }
	  //构造方法,创建容量为size的空表
	    public SeqList(int size) {
	        this.element = new Object[size];
	        this.len = 0;
	    }
	  //判断顺序表是否空,若空返回true,否则返回false
	    public boolean isEmpty() {
	        return this.len == 0;
	    }
	   //返回顺序表长度,
	    public int length() {
	        return this.len;
	    }
	   //返回第i(≥0)个元素。若i<0或大于表长则返回null
	    public T get(int i) {
	        if (i >= 0 && i < this.len) {
	            return (T) this.element[i];
	        }
	        return null;
	    }
	  //设置第i(≥0)个元素值为x。若i<0或大于表长则抛出序号越界异常;若x==null,不操作
	    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 + ""); // 抛出序号越界异常
	        }
	    }  

线性表的插入和删除

	//插入数据 
	    public void insert(int i, T x) {
	        if (x == null)
	            return;
	        // 若数组满,则扩充顺序表容量
	        if (this.len == element.length) {
	            // temp也引用elements数组
	            Object[] temp = this.element;
	            // 重新申请一个容量更大的数组
	            this.element = new Object[temp.length * 2];
	            // 复制数组元素,O(n)
	            for (int j = 0; j < temp.length; j++) {
	                this.element[j] = temp[j];
	            }
	        }
	        // 下标容错
	        if (i < 0)
	            i = 0;
	        if (i > this.len)
	            i = this.len;
	        // 元素后移,平均移动len/2
	        for (int j = this.len - 1; j >= i; j--) {
	            this.element[j + 1] = this.element[j];
	        }
	        this.element[i] = x;
	        this.len++;
	    }
	//在顺序表最后插入x元素
	    public void append(T x) {
	        insert(this.len, x);
	    }
	//删除
	    public T remove(int i) {
	        if (this.len == 0 || i < 0 || i >= this.len) {
	            return null;
	        }
	        T old = (T) this.element[i];
	        // 元素前移,平均移动len/2
	        for (int j = i; j < this.len - 1; j++) {
	            this.element[j] = this.element[j + 1];
	        }
	        this.element[this.len - 1] = null;
	        this.len--;
	        return old;
	    }
	   // 删除线性表所有元素
	    public void removeAll() {
	        this.len = 0;
	    }

   个人总结:线性表包含线性表抽象数据类型、顺序表、单链表、循环单链表、循环双向链表、静态链表。今天我主要讲的是线性表的基本概念、线性表抽象数据类型、顺序表。线性表除了第一个元素没有前驱元素和最后一个元素没有后继元素外,其他元素有且只有一个直接元素和一个直接后继元素。在逻辑上,数据元素之间存在着“一对一”的逻辑关系。对于原本的数据小量和要插入的数据小量,建议使用线性表,运行效率高。对于数据大量或者插入的数据大量的时候,不建议使用。因为插入的过程中元素的位置改变很多,这样运行效率就比较低。顺序表其实和线性表差不多的,不同的是顺序表是先把数据按一定的规则排好,这样也提高了数据的查找的效率。再和大家分享最近发生在我身边的一个小故事,我有一个朋友她和我说,“还有一周时间就要考试了,可她对自己一点信心都没有”。然后,我就回复她,从现在开始把所有的精力都放在复习上,全力以赴的对待这件事情。可是意外的是她居然还留一个上午的时间去做别的事情,谁都没有想到一个完全没有信心的人,在考试的过程中。就差那么一点点,就离成功的边缘就差那么一点点。如果当初她再努力一点点,如果当初听我的把所有精力放在这次考试上,可能结果就不会和现在那样。出于孟子的“鱼,我所欲也,熊掌亦我所欲也;二者不可得兼,舍鱼而取熊掌者也。”其实这句话想告诉我们的是“不是说二者必然不可兼得,而是强调当如果不能兼得的时候,我们应当如何取舍。”

发布了37 篇原创文章 · 获赞 8 · 访问量 5941

猜你喜欢

转载自blog.csdn.net/weixin_43741599/article/details/97496705