数据结构---线性表的顺序表示

(一)数组杂识

数组操作的复杂性:

数组操作的时间和空间复杂性如下表所示:

时间复杂性

算法       平均情况最坏情况
  插入(增)        O(1)O(1)
删除(删)       O(n) O(n)
查找(查)      O(n) O(n)
遍历+赋值(改)     O(n) O(n)

空间复杂度:

最坏情况下的空间复杂度为O(n)。

数组

数组的所有数据元素都存储在主存储器中的连续位置。 数组名称表示主存储器中的基地址或第一个元素的地址。 数组的每个元素都由适当的下标表示。
可以用三种方式定义数组的索引。

  • 0(从零开始查找):数组的第一个元素是arr[0]
  • 1(基于一个查找):数组的第一个元素是arr [1]
  • n(基于n的查找):基于数组的第一个元素,可以定位任何随机下标值。
  • 注意:如果数组的大小是n,则最后一个元素使用n-1来访问。 
  • 某一数组A[i] 元素的字节地址 = 基地址 + size * (i距离首地址的下标差值) 

 (二)线性表的顺序表示  

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。 

 顺序表中存放数据的特点和数组这种数据类型完全吻合,所以顺序表的实现使用的是数组。

     使用顺序存储结构存储的数据,第一个元素所在的地址就是这块存储空间的首地址。通过首地址,可以轻松访问到存储的所有的数据,只要首地址不丢,数据永远都能找着(班级里,按照学号去叫人,肯定能念到每一个同学,想找谁,就念谁)。

     在建立顺序表时,需要预先申请内存空间,还需要实时记录顺序表的长度和顺序表本身申请的内存大小,便于后期对顺序表中的数据元素进行调取。
 
  自定义顺序表的结构:

​
//----线性表的动态分配顺序存储结构--------
#define LIST_INIT_SIZE 100//线性表存储空间的初始分配量

typedef struct {
    int * head;//声明了一个名为head的长度不确定的数组,也叫“动态数组”:存储空间基址
    int length;//当前顺序表的长度
    int size;// 顺序表分配的存储容量
}SqList;

​

 初始化顺序表:

//初始化
SqList InitSqList()
{
	 SqList q ;
	 q.head = (int*)malloc(LIST_INIT_SIZE * sizeof(int));//构造一个空的顺序表,动态申请存储空间
	 assert(q.head);//如果q.head为空,返回空
	 q.lenth = 0;//空表的长度初始化为0
	 q.size = LIST_INIT_SIZE;//空表的初始存储空间为Size
	 return q;//返回头结点,也可以不返回
}

完整代码:

​
#include  <stdio.h>
#include  <stdlib.h>
#include  <assert.h>
//----线性表的动态分配顺序存储结构--------
#define  LIST_INIT_SIZE 10//线性表存储空间的初始分配量
typedef int Data;//抽象数据类型
typedef struct
{
	int* head;//声明了一个名为head的长度不确定的数组,也叫“动态数组”:存储空间基址
	int  lenth;//当前顺序表的长度
	int  size;// 顺序表分配的存储容量
}SqList;

//初始化
SqList InitSqList()
{
	 SqList q ;
	 q.head = (int*)malloc(LIST_INIT_SIZE * sizeof(int));//构造一个空的顺序表,动态申请存储空间
	 assert(q.head);//如果q.head为空,返回空
	 q.lenth = 0;//空表的长度初始化为0
	 q.size = LIST_INIT_SIZE;//空表的初始存储空间为Size
	 return q;//返回头结点,也可以不返回
}
//增:这里采用直接尾插顺序表,作为表的最后一个元素;但还有按指定位置插入;在表头插入;
void InsertSqList(SqList* q,Data data)
{
	if (q->lenth > q->size) return;
	q->head[q->lenth] = data;
	q->lenth++;
}
//删除:这里是按指定位置删除; num:指定下标
void DeleteSqList(SqList* q, int num)
{
	assert(q->head);
	if (q->lenth <= num)
	{
		printf("长度传入失败,请检查后输入\n");
		return;
	}
	 
	for (int i = num; i < q->lenth; i++)
	{
		q->head[i] = q->head[i + 1];
	}
	
	q->lenth--;
}
//遍历
void Print(SqList  q)
{
	if (q.head == NULL)
	{
 	printf("p为空 \n");
	return;
	}
	for (int i = 0; i < q.lenth; i++)
	{
		printf("%d  ",q.head[i]);
	}printf("\n");
}
//查:num:指所查元素下标
Data researchSqList(SqList q, int num)
{
	assert(q.head);
	if (q.lenth <= num)
	{
		printf("长度传入失败,请检查后输入\n");
		return;
	}
	return q.head[num];
}
//改:num:指所改元素下标,a:修改数据
void modifySqList(SqList* q,Data a,int num)
{
	assert(q->head);
	if (q->lenth <= num)
	{
		printf("长度传入失败,请检查后输入\n");
		return;
	}
	q->head[num] = a;
}

int main()
{
	  SqList p=InitSqList();
	  printf("增加10个元素:\n");
	  for (int i = 0; i < 10; i++)
	  {
         InsertSqList(&p, 3+i);
	  }
	  Print(p);
	  printf(" 修改坐标为3的元素:\n");
	  modifySqList(&p, 77, 3);
	  Print(p);
	  printf("删除坐标为2的元素:\n");
	  DeleteSqList(&p, 2);
	  Print(p);
	  printf("查找坐标为4的元素:\n");
	  printf("%d",researchSqList(p, 4));
	   
	  return 0;
}

​

总结:

顺序表的实现,借用了数组这一数据类型,优点是在对数据进行遍历时,数据在连续的物理空间中存放,查找,修改,遍历的速度比较快。但是由于数组本身的限制,在向顺序表中新增(若按指定位置插入)或者删除数据元素时,如果被操作位置后续有很多数据元素,后续所有的数据元素都需要前移,最后虽然实现了功能,但是程序总体效率不高。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

尘 关

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

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

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

打赏作者

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

抵扣说明:

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

余额充值