1.顺序表存储(典型的数组)
原理:顺序表存储是将数据元素放到一块连续的内存存储空间,相邻数据元素的存放地址也相邻(逻辑与物理统一)。
优点:(1)空间利用率高。(局部性原理,连续存放,命中率高)
(2)存取速度高效,便于随机存取,通过下标来直接存储。
原理:顺序表存储是将数据元素放到一块连续的内存存储空间,相邻数据元素的存放地址也相邻(逻辑与物理统一)。
优点:(1)空间利用率高。(局部性原理,连续存放,命中率高)
(2)存取速度高效,便于随机存取,通过下标来直接存储。
缺点:(1)插入和删除比较慢,但是它存储结构跟数组是一样,所以也就不便于插入和删除。当顺序表较大时,插入和删除都会引起大量数据的 移动。如果插入和删除频繁操作的话,最好使用链表的数据结构。顺序表一般存储不经常变动的数据。
(2)不可以增长长度,有空间限制,当需要存取的元素个数可能多于顺序表的元素个数时,会出现"溢出"问题.当元素个数远少于预先分配的空间时,空间浪费巨大。
时间性能 :查找 O(1) ,插入和删除O(n)。
(2)不可以增长长度,有空间限制,当需要存取的元素个数可能多于顺序表的元素个数时,会出现"溢出"问题.当元素个数远少于预先分配的空间时,空间浪费巨大。
时间性能 :查找 O(1) ,插入和删除O(n)。
一个顺序表的存储数据后,基本操作有:构造, 置空,取表长,取表元素,插入,删除,查找,显示。
java代码:
package PracticeExample.SeqList;
/*
* 学习网址:https://blog.csdn.net/dingjing1994/article/details/71694573
*
* */
public class SeqList<T> extends Object{
//对象数组存储顺序表的数据元素,protected声明
protected Object[] element ;
//顺序表中元素的个数(表长)
protected int n;
//构造容量为length的空表
public SeqList(int length){
//申请数组的存储空间,元素为null
this.element = new Object[length];
//若length<0,则跑出负数组长度异常java.lang.NegativeArraySizeException
this.n = 0 ;
}
//无参构造函数,创建默认容量的空表,构造方法重载
public SeqList(){
//调用本类已经声明的指定参数列表的构造方法
this(64) ;
}
//构造顺序表,由values数组提供元素
public SeqList(T values[]){
//创建容量为values.length的空表
//若values==null,则用空对象调用方法,抛出NullPointerException异常
this(values.length) ;
//复制数组元素,T(n) = O(n)
for(int i=0;i<values.length;i++){
//对象引用赋值
this.element[i] = values[i] ;
}
this.n = element.length ;
}
//返回顺序表所有元素的描述字符串,形式为“(,)”,覆盖Objcet类的toString()方法
public String toString() {
//返回类型
String str = this.getClass().getSimpleName() + "(";//类的名字
if (this.n > 0) {
str += this.element[0].toString();
}
for (int i = 1; i < this.n; i++) {
//执行T类的toString()方法,运行时多态
str += "," + this.element[i].toString(); //打印元素的名字
}
//空表返回()
return str + ")";
}
/**********************************************************************
*线性表的主要操作
* **********************************************************************/
//取表长度,也就是有几个元素
public int size(){
return this.n;
}
//置空操作
public void clear(){
this.n =0;
}
//判空操作
public boolean isEmpty(){
return this.n == 0 ;
}
//按位查找,返回第i个元素,下标从0开始
public Object Get(int i) throws Exception{
//判断 i 是否合法
if( i <0 || i > this.n -1)
throw new Exception("第"+i+"个元素不存在");
return (T)this.element[i] ;
}
//按值查找首次出现的与x相等的元素,返回元素在顺序表中的位置下标,从0开始
public int Locate(T x) {
for (int i=0; i<this.n; i++) {
if ((T) this.element[i] == x) return i;
if (x.equals(this.element[i])) {
return i;
}
}
return -1;
}
//判断是否包含关键字为key的元素
public boolean Contains(T key){
return this.Locate(key)!=-1 ;
}
//插入操作
//插入x作为第i个元素,x!=null,返回x序号。若x==null,则抛出空对象异常。T(n)=O(n)。
//对序号i采取容错措施,若i<0,则插入x在最前;若i>n,则插入x在最后
public int Insert(int i,T x)throws Exception{
if(x == null){
//抛出空指针异常
throw new NullPointerException("x == null") ;
}
//插入位置i容错,插入在最前
else if(i<0){
i = 0 ;
}
//插入位置i容错,插入在最后
else if(i>this.n){
i = this.n ;
}
//数组引用赋值,source也引用element
Object source[] = this.element ;
//若数组空间已满,则扩充顺序表的数组容量
if(this.n == element.length) {
//重新申请一个容量更大的数组
this.element = new Object[source.length * 2];
//复制当前数组前i-1个元素
for (int j = 0; j < i; j++) {
this.element[j] = source[j];
}
source=null;
}
//从i开始至表尾的元素向后移动,次序从后向前
for(int j=this.n-1;j>=i;j--){
this.element[j+1] = this.element[j] ;
}
this.element[i] = x;
this.n++ ;
//返回x的序号
return i ;
}
//按值删除操作
public boolean Delete(T x) throws Exception {
if (this.n == 0) throw new Exception("线性表为空,无法实现删除操作");
for (int i = 0; i < this.n; i++) {
if ((T) this.element[i] == x) {
for (int j = i; j < this.n - 1; j++) {
//元素前移一个位置
this.element[j] = this.element[j + 1];
}
//设置数组元素对象为空,释放原引用实例
this.element[this.n - 1] = null;
this.n--;
return true;
}
}
return false;
}
//按位删除操作
public T Remove(int i) throws Exception {
if (this.n == 0) throw new Exception("线性表为空,无法实现删除操作");
if (i < 0 || i > this.n) throw new Exception("该元素下标不存在,请输入正确的元素位置");
if (this.n > 0 && i >= 0 && i < this.n) {
//old中存储被删除元素
T old = (T) this.element[i];
for (int j = i; j < this.n - 1; j++) {
//元素前移一个位置
this.element[j] = this.element[j + 1];
}
//设置数组元素对象为空,释放原引用实例
this.element[this.n - 1] = null;
this.n--;
//返回old局部变量引用的对象,传递对象引用
return old;
}
return null;
}
// 测试函数
public static void main(String args[]) throws Exception {
//创建一个空表
SeqList<Integer> obj=new SeqList<Integer>();
//顺序表判空
if(obj.isEmpty()){
System.out.println("\n"+"顺序表"+obj.toString()+"为空.");
}
else {
System.out.println("顺序表"+obj.toString()+"的元素个数为:"+obj.size()+"\n");
System.out.println("顺序表"+obj.toString()+"的空间大小为:"+obj.element.length+"\n");
}
//顺序表插入元素操作
System.out.println("顺序表"+obj.toString()+"插入操作:");
try {
System.out.println("元素插入的位置为:"+obj.Insert(0,0)+",插入元素为:"+"0");
System.out.println("元素插入的位置为:"+obj.Insert(1,1)+",插入元素为:"+"1");
System.out.println("元素插入的位置为:"+obj.Insert(2,2)+",插入元素为:"+"2");
System.out.println("元素插入的位置为:"+obj.Insert(-1,-1)+",插入元素为:"+"-1");
System.out.println("元素插入的位置为:"+obj.Insert(10,10)+",插入元素为:"+"10");
//顺序表判空,测试插入是否成功
if(obj.isEmpty()){
System.out.println("\n"+"顺序表obj为空.");
}
else {
System.out.println("顺序表"+obj.toString()+"的元素个数为:"+obj.size()+"\n");
System.out.println("顺序表"+obj.toString()+"的空间大小为:"+obj.element.length+"\n");
}
}catch (Exception ex)
{
throw ex;
}
//顺序表按值删除操作,非法元素
System.out.println("顺序表"+obj.toString()+"的按值删除操作:");
try {
boolean delete = obj.Delete(8);
if(delete){
System.out.println("删除元素 8 成功");
}
else {
System.out.println("删除元素 8 失败");
}
// 顺序表按值删除操作,删除合法元素
boolean delete1 = obj.Delete(-1);
if(delete1){
System.out.println("删除元素 -1 成功");
}
else {
System.out.println("删除元素 -1 失败");
}
}catch (Exception ex){
throw ex;
}
//创建容量为10的空表
SeqList obj1=new SeqList(10);
//通过判空操作,测试创建是否成功
if(obj1.isEmpty()){
System.out.println("\n"+"顺序表"+obj1.toString()+"为空.");
}
else {
System.out.println("顺序表"+obj1.toString()+"的元素个数为:"+obj1.size()+"\n");
System.out.println("顺序表"+obj1.toString()+"的空间大小为:"+obj1.element.length+"\n");
}
//顺序表插入元素操作
System.out.println("顺序表"+obj1.toString()+"的插入操作:");
try {
System.out.println("元素插入的位置为:"+obj1.Insert(0,1)+",插入元素为:"+"0");
System.out.println("元素插入的位置为:"+obj1.Insert(1,2)+",插入元素为:"+"1");
System.out.println("元素插入的位置为:"+obj1.Insert(2,3)+",插入元素为:"+"2");
System.out.println("元素插入的位置为:"+obj1.Insert(-1,4)+",插入元素为:"+"-1");
System.out.println("元素插入的位置为:"+obj1.Insert(10,5)+",插入元素为:"+"10");
System.out.println("当前顺序表+"+obj1.toString()+ "的内容为"+obj1.toString());
//顺序表判空,测试插入是否成功
if(obj1.isEmpty()){
System.out.println("\n"+"顺序表为空.");
}
else {
System.out.println("顺序表"+obj1.toString()+"的元素个数为:"+obj1.size()+"\n");
System.out.println("顺序表"+obj1.toString()+"的空间大小为:"+obj1.element.length+"\n");
}
}catch (Exception ex)
{
throw ex;
}
//顺序表按位删除操作,非法元素
System.out.println("顺序表"+obj1.toString()+"的按位删除操作:");
// 顺序表按位删除操作,删除合法位置元素
try {
try {
Object pos = obj1.Remove(3);
System.out.println("删除第 3 个位置的元素成功 \n");
}catch ( Exception ex){
System.out.println("删除第 3 个位置的元素失败 \n");
throw ex;
}
// try {
// Object pos1 = obj1.Remove(8);
// System.out.println("删除第 8 个位置的元素成功");
//
// }catch ( Exception ex){
// System.out.println("删除第 8 个位置的元素失败");
// throw ex;
// }
}catch (Exception ex)
{
throw ex;
}
Integer a[] = {3,1,5,7,2,4,9,6,10,8};
SeqList<Integer> obj2 = new SeqList(a);
//通过判空操作,测试创建是否成功
if(obj2.isEmpty()){
System.out.println("\n"+"顺序表"+obj2.toString()+"为空.");
}
else {
System.out.println("顺序表"+obj2.toString()+"的元素个数为:"+obj2.size()+"\n");
System.out.println("顺序表"+obj2.toString()+"的空间大小为:"+obj2.element.length+"\n");
}
//顺序表查找操作
System.out.println("顺序表"+obj2.toString()+"的按值查找操作:");
System.out.println("查找元素 2 ");
int loc=obj2.Locate(2);
if(loc==-1){
System.out.println("顺序表"+obj2.toString()+"没有该元素");
}
else {
System.out.println("元素 2 在顺序表的下标为"+loc);
}
System.out.println("顺序表"+obj2.toString()+"的按位查找操作:");
try {
System.out.println("查找元素下标2处的元素值 ");
try {
System.out.println("元素下标2处的元素值为:"+obj2.Get(2).toString());
}catch (Exception ex){
System.out.println("输入的元素下标异常");
throw ex;
}
System.out.println("查找元素下标10处的元素值 ");
try {
System.out.println("元素下标10处的元素值为:"+obj2.Get(10).toString());
}catch (Exception ex){
System.out.println("输入的元素下标异常");
throw ex;
}
}catch (Exception ex){
throw ex;
}
}
}
参考网址:顺序表--Java实现