数据结构 顺序表的实现

一、线性表的顺序存储结构

       顺序存储结构是存储结构中的一种,顺序表首先是一种线性表,在此基础上要求逻辑结构上相邻的数据元素其物理存储结构也相邻,且表中的结点依次存放在计算机内存中一组地址连续的存储单元中,之间不能存在空隙,如下图所示:

        将表中元素一个接一个存入一组连续的存储单元中,这种存储结构就是顺序结构。

        只要确定了起始位置,表中任意的元素都可以通过下列公式得到:  LOC\left ( a_{i} \right )=LOC\left ( a_{1} \right )+\left ( i-1 \right )\times L,L  我们可以轻松访问到顺序表中的所有数据。

二、顺序表的实现 

       顺序表的实现使用的是数组,这是根据其存储结构所确定的。

      (1)顺序存储结构的建立

#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2

typedef int ElemType;

typedef struct 
{
	ElemType *data;
	int maxsize;
	int cursize;
}SeqList;

       定义一个结构体,其中包含三个重要属性,数据值data,线性表的最大存储容量maxsize,当前线性表的长度cursize。这三个属性可以描述顺序存储结构。 两条宏定义语句方便顺序表满时动态扩容。

    (2)顺序表的初始化

void Init_SeqList(SeqList &tlist)
{
	tlist.data = (ElemType*)malloc(sizeof(ElemType)*SEQ_INIT_SIZE);
	if(tlist.data == NULL) exit(1);
	tlist.maxsize = SEQ_INIT_SIZE;
	tlist.cursize = 0;
}

        顺序表的初始化就是申请空间,再更改结构体里的属性值。如果申请不到空间就直接退出。

     (3)基本信息的获取与判断

int GetCapacity(SeqList &tlist)
{
	return tlist.maxsize;
}
int GetSize(SeqList &tlist) 
{
	return tlist.cursize;
}
bool Is_Empty(SeqList &tlist)
{
	return GetSize(tlist) == 0;
}
bool Is_Full(SeqList &tlist)
{
	return GetSize(tlist) == GetCapacity(tlist);
}

      包括顺序表当前最大存储容量,存储元素个数,以及判空和判满。 

      (4)增容函数

bool Inc_Capa(SeqList &tlist)
{
	ElemType *newdata = (ElemType*)realloc(tlist.data,sizeof(ElemType)*tlist.maxsize*SEQ_INC_SIZE);
	if(NULL == newdata) return false;
	tlist.data = newdata;
	tlist.maxsize *= SEQ_INC_SIZE;
	return true;
}

        当顺序表满时进行动态增容工作,newdata申请两倍顺序表最大容量的空间,申请失败就返回false;修改顺序表最大容量值为原来的两倍。

      (5)按位置插入

bool Insert_Pos(SeqList &tlist,int pos,ElemType val)
{
	if(pos < 0 || pos > tlist.cursize) return false;

	if(Is_Full(tlist) && !Inc_Capa(tlist))
	{
		return false;
	}

	for(int i = tlist.cursize; i> pos; --i)
	{
		tlist.data[i] = tlist.data[i-1];
	}
	tlist.data[pos] = val;
	tlist.cursize +=1;
	return true;
}

        在pos位置插入值为val的元素,先要判断要插入的位置是否合法,不合法的话返回false;如果顺序表已满,调用扩容函数,扩容失败的话也返回false。接下来就是从最后一个元素开始,将数组元素依次后移,在pos位放入val值,不能忘记顺序表长度要加1。

       (6)按位置删除

bool Erase_Pos(SeqList &tlist,int pos)
{
	if(pos < 0 || pos > tlist.cursize-1) return false;
	tlist.cursize-=1;
	for(int i = pos ; i < tlist.cursize;++i)
	{
		tlist.data[i] = tlist.data[i+1];
	}
	return true;
}

         删除pos位置的元素,和插入操作相同,先判断删除位置的合法性;将pos之后的元素依次前移,删除元素后,顺序表表长减1。

      (7)按值查找

int FindValue(SeqList &tlist,ElemType val)
{
	int pos = -1;
	for(int i = 0;i<tlist.cursize;++i)
	{
		if(tlist.data[i] == val)
		{
			pos = i;
			break;
		}
	}
	return pos;
}

      在顺序表中查找值为val的位置,返回位置的下标;如果返回-1说明顺序表中没有值为val的元素。

      (8)按值删除

void Remove(SeqList &tlist,ElemType val)
{
	Erase_Pos(tlist,FindValue(tlist,val));
}

void Remove_All(SeqList &tlist,ElemType val)
{
	int j = 0;
	for(int i = 0;i<tlist.cursize;++i)
	{
		if(val != tlist.data[i])
		{
			tlist.data[j] = tlist.data[i];
			++j;
		}
	}
	tlist.cursize = j;
}

       第一个函数删除第一个值为val的函数,借助查找函数和按位置删除函数可以很容易实现;第二个函数删除所有值为val的函数,这时需要一点小技巧,借助i,j 降低时间复杂度。

    (9)打印顺序表

void Print_SeqList(SeqList &tlist)
{
	printf("Capacity: %d \n",tlist.maxsize);
	printf("size :    %d \n",tlist.cursize);
	for(int i = 0;i<tlist.cursize;++i)
	{
		printf("%d ",tlist.data[i]);
	}
	printf("\n");
}

 三、总结 

       顺序存储结构的主要优点是节省存储空间,分配给数据的存储空间是连续的且仅用于存放数据,没有占用额外空间;在进行查找等操作时很方便。顺序表的缺点也很明显,在进行插入删除等操作时,再某些情况下移动数据元素的次数过多,不便于修改。

      

 

 

     

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用c++实现顺序表:多文件编程,层次清晰,函数有注释 SeqList();//构造函数,存储的元素个数设为0 bool setLength(size_t length);//设置已经存储的元素个数 bool addElement(ElemType element);//把某个元素添加到顺序表末尾 bool addElement(ElemType element , size_t n);//插入一个元素,使其成为第n个元素,其余元素后移 bool delElement();//删除所有的元素 bool delElement(size_t n);//删除第n个元素 bool delElement(string elementDetailType,string elementDetail);//通过某个元素细节找到元素,把这个元素删除 bool replaceElement(ElemType element , size_t n);//使用一个元素,替换掉第n个元素 bool swapElement(size_t n1 , size_t n2);//把第n1个元素和第n2个元素交换 ElemType* getElement();//得到数组头的指针 ElemType* getElement(size_t n);//得到第n个元素的指针 size_t getLength();//得到存储的元素个数 size_t getMaxSize();//得到顺序表容量 bool showElementDetail();//输出所有的元素细节 bool showElementDetail(size_t n);//输出第n个元素的细节 bool showElementDetail(string elementDetailType,string elementDetail);//通过某个元素细节找到元素,输出元素所有细节 size_t findElement(string elementDetailType,string elementDetail);//通过某个元素细节找到元素位置 static int inputAInt(int min = 0,int max = 9,int defaultValue = -1);//从键盘读取,限制为一个min到max间的整数,非法情况返回defaultValue void startControlLoop();//打开控制界面 ~SeqList();//析构函数

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值