顺序表(详解)- C++(线性表顺序存储结构)

51 篇文章 13 订阅
47 篇文章 2 订阅

问题引入

        在数据结构中,线性表是一种很重要的线性结构。线性表分为多种类型,常见的如顺序表、链表等,如果此时此刻你对“顺序表(顺序存储)”感到困惑,那就继续看下去,我们一步一步去剖析。

        如果你想要进一步了解“链表”——1.“顺序创建(尾插法)”、2.“逆序创建(头插法)”,

        请参考文章 : 1. “链表(详解)- C++(顺序创建链表-尾插法)”(点击查看)

                              2.  “链表(详解)- C++(逆序创建链表-头插法)”(点击查看)。

问题分析

        如果想要搞明白“线性表”,首先你要明白两个问题:

        1.什么是线性表?

        答:一个“线性表”(linear list)是n个数据元素的有限序列。

        2.“顺序表(顺序存储)”的特点是什么?

        答:(1)顺序表顺序存储 可随机存取,即可以任意从任何一个位置插入、删除元素。

                (2)用一组连续的存储单元储存线性表的数据元素(这组存储单元必须是连续的)。也即“使用数组对元素进行存储”。

                (3)表中元素个数叫表长,元素个数可以有多个,也可以为0。某个元素的上一个元素叫直接前驱元素,下一个元素叫直接后继元素。

                (4)优点:可以快速存储表中任意位置的元素的值;无需为表中的逻辑关系增加额外的存储空间。

                (5)缺点:插入和删除元素需移动大量的元素;容易生成存储空间"碎片"。

顺序表整体结构分析

        顺序表 也即 线性表的一种顺序存储结构,用一组连续的存储单元储存线性表的数据元素(这组存储单元必须是连续的)。也即“使用数组对元素进行存储”。我们可以借助数组的思想实现顺序表的顺序存储,分配依次存储空间后,接下来我们就可以根据位置插入、删除元素,如下图,如果仍然感到困惑,接下来我们分过程去看元素入“顺序表”和出“顺序表”的过程。

 

元素入顺序表分析

        对于顺序表而言,采用的是“顺序存储”的方式,因此我们只要指定好一定空间,按照位置进行插入元素即可,只要该位置无元素或者顺序表未满,那么就可以在指定位置插入数据,而不用事先设置指针指向该位置。

        例如:

                        在链队列中插入元素33。

        分析:首先对顺序表进行“遍历”,查找指定位置或者找到一个空位插入数据,“插入”的实质其实就是先将表长 +1,之后将“指定位置”后的所有元素向后移动一个位置“从后向前”依次后移,避免数据被前面的元素覆盖,如图1、2。

        (务必注意: “表长”的变化 和 移动的方向。)

图1

 

图2

元素出顺序表分析

          例如:

                        在链队列中删除元素33。

        明白了元素入顺序表,那么元素的出顺序表与入顺序表过程相似。分析:首先对顺序表进行“遍历”,查找指定位置上的元素,“删除”的实质其实就是查找到要删除的元素,然后将“指定位置”后的所有元素向前移动一个位置,即覆盖要删除的元素,最后表长 -1“从前向后”依次前移,每一个元素覆盖上一个元素,如图1、2。

     (务必注意: “表长”的变化 和 移动的方向。)

图1

 

 

图2

代码实现

        说明:采用C++语言,编译环境为DevC++。

//导入头文件
#include<malloc.h>
#include<iostream>
using namespace std;

//定义线性表
typedef struct{
	int *elem;//数据元素
	int length;//当前长度
	int listsize;//存储容量
}SqList;

//初始化线性表
void InitSqList(SqList &L){
	L.elem=(int *) malloc(50*sizeof(int));
	L.length=0;//空表
	L.listsize=50;
}

//创建顺序表 
void CreatSqList(SqList &L){
	 int i=0;
	 cout<<"请输入数据,以-10000结束:"<<endl;
	 cin>>L.elem[i];
	 while(L.elem[i]!=-10000 && L.length<L.listsize){
		 ++L.length;
		 i++;
		 cin>>L.elem[i];
	 }
}

//输出
void PrintSqList(SqList &L){
	int i;
	cout<<"\n线性表中的全部元素为:\n";
	for(i=0;i<L.length;i++)
		cout<<L.elem[i]<<' ';
	cout<<endl<<endl;
}

//查找,若不存在输出0
int LocateSqList(SqList L,int e){
	int i=0;
	int *p=L.elem;
	while(i<L.length){
		p++;
		i++;
		if((*p)==e)
			return i+1;
		if(i==L.length) 
			return 0;
	}
}

//插入
int InsertSqList(SqList &L,int i,int h){
	int *p;
	int *q;
	p=&(L.elem[L.length+1]);
	q=&(L.elem[i-1]);
	for(p;p>=q;p--)
		*p=*(p-1);
	++L.length;//插入前 表长+1 
	*(q)=h;
	return 0;//返回0表示成功
}

//删除
int DeleteSqList(SqList &L,int m){
	int *p;
	int *q;
	p=&(L.elem[L.length]);
	q=&(L.elem[m]);
	for(q;q<p;q++)
		*(q-1)=*q;
	--L.length;//删除后 表长-1 
	return 0;//返回0表示成功
}

//主函数
int main(){
	SqList L;
	int e;
	int i;
	int h;
	int m;
	InitSqList(L);
	CreatSqList(L);
	PrintSqList(L);
	cout<<"请输入要查找的数据元素:"<<endl;
	cin>>e;
	cout<<"数据"<<e<<"在表中第 "<<LocateSqList(L,e)<<" 个位置。"<<endl;
	cout<<"请输入第几个位置插入数据元素:"<<endl;
	cin>>i;
	cout<<"请输入要插入的新数据元素:"<<endl;
	cin>>h;
	cout<<InsertSqList(L,i,h)<<endl;
	PrintSqList(L);//输出更改后的线性表
	cout<<"请输入第几个位置删除数据元素:"<<endl;
	cin>>m;
	cout<<DeleteSqList(L,m)<<endl;
	PrintSqList(L);//输出更改后的线性表
}

运行结果

 

写在最后:

        读两遍下来,如果仍然有不清楚的地方,可在评论区留言。

        如果你有其他感到困惑的问题,欢迎留言。

  • 8
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等日出看彩虹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值