数据结构 ---- 线性表
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);
结果:
单链表
以上是关于数据结构 ---- 线性表的主要内容,如果未能解决你的问题,请参考以下文章