【精讲数据结构02】线性表、顺序表

目录

一、什么是线性表

二、什么是顺序表

三、定义顺序表的结构类型SqList

1.静态与动态顺序表

2.举例

四、线性表的初始化

五、顺序表的功能函数

1、销毁线性表

2、清空线性表

3、求线性表的长度

4、判断线性表是否为空

5、顺序表的取值(输出第i个数据元素)

6、顺序表的查找

7、检查容积

8、顺序表第i位置插入一个元素的插入

9、顺序表的头插和尾插

10、顺序表中删除第i位置的元素

11、顺序表中头删和尾删


😀写在前面:本文中的代码均以C语言呈现

一、什么是线性表

        线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。
        常见的线性表:顺序表、链表、栈、队列、字符串。。。
        线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上不是连续的。线性表在物理上存储时,通常以数组和链式结构的形式存储。

二、什么是顺序表

        顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增、删、查、改。

三、定义顺序表的结构类型SqList

1.静态与动态顺序表

(1)静态顺序表:使用定长数组存储元素。
 

(2)动态顺序表:使用动态开辟的数组存储。

2.举例

这里是以动态顺序表为例子进行举例,定义一个顺序表

typedef struct{
        /*所创建的链表每个数据元素的类型*/
}ElemType;


/*
举个栗子哦,线性表是学生的信息表格,每个学生的信息包括姓名、性别、C语言考试成绩。即线性表中数据元素为每个学生,数据项为姓名,性别,成绩。则可这样创建结构类型:

typedef struct{
        char name[20];
        char gender;
        double count;
}ElemType;

这样定义完成后在Sqlist结构中可直接引用
*/


typedef struct{
	 ElemType *elem;//存储空间的基地址

	int length;//当前的线性表长度

	int listsize;//此线性表最大长度,一般不太需要给出这一项
}Sqlist;


Sqlist L;//这样就定好了一个顺序表L;

线性表与数组的对比

对比 线性表 数组 定义 Sqlist L; int arr[100]; 第i个元素 L.elem[i] arr[i] 第i个元素地址

&L.elem[i]

也就是L.elem+i也是该数据元素结构体内部变量的首地址(例如:&(L.elem[i].count))

&arr[i]

四、线性表的初始化

int InitList1(Sqlist *l){
    l->elem=(ElemType *) malloc(100*sizeof(ElemType ));//为顺序表分配空间
    if(!l->elem)return 0;
    l->length= 0;//空表长度为0
    l->listsize=100;顺序表最大长度
    return 1;
}
    
/*返回1则创建成功*/
在主函数中调用如下:


Sqlist L;
InitList(&L);

五、顺序表的功能函数

1、销毁线性表

释放了内存后将指针置空是一个很好的习惯,这样避免野指针的出现。

void DestroyList(Sqlist *L){
    if(L->elem) { 
        free(L->elem);//free函数释放内存
        L->elem=NULL;
    }
}

2、清空线性表

void ClearList(Sqlist *L){
    L->lenght=0;
}

3、求线性表的长度

int GetList(Sqlist *L){
    return (L->lenght);
}

4、判断线性表是否为空

int IsEmpty(Sqlist *L){
    if(L->lenght==0)return 1;
    else return 0; 
}

5、顺序表的取值(输出第i个数据元素)

将第i个位置的元素赋值给变量e。

int GetElem(Sqlist *L,int i,ElemType *e){
    if(i<1||i>(L->lenght))return 0;//位置i是否合理
    *e=L->elem[i-1];
    return 1;
}

6、顺序表的查找

在顺序表中查找,如果找到了就返回对应的位置信息。

int LocateElem(Sqlist *L,ElemType e){
    int i;
    for(i=0;i<L->lenght;i++){
           if(L->elem[i]==e)return i+1;
    return 0;
}

7、检查容积

检查当前的顺序表的长度够不够用,如果不够,扩容一倍。

void CheckCapacity(Sqlist * L)
{
	if (L->length == L-> listsize)
	{
		ElemType* tmp = (ElemType*)realloc(L->elem, sizeof(ElemType) * L->listsize * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		L->a = elem;
		L->listsize *= 2;
	}
}

8、顺序表第i位置插入一个元素的插入

int ListInsert_sq(Sqlist *L,int i,ElemType e){
         int j;
        if(i<1||i>(L->lenght))return 0;
        if((L->lenght)==(L->listsize)return 0;
        for(j=L->lenght;j>i-1;j--)
                L->elem[j+1]=L->elem[j];
        L->elem[i-1]=e;
        L->lenght++;
        return 1;
}

9、顺序表的头插和尾插

//尾插法插入新元素
void PushBack(Sqlist* L, ElemType x)
{
	//L->a[L->lenght] = x;
	//L->slenght++;

	CheckCapacity(L);//检查一下顺序表满不满

	L->a[L->lenght++] = x;

}



//头插法插入新元素
void PushFront(Sqlist* L,ElemType x)
{
	
	SLCheckCapacity(L);//检查一下顺序表满不满

	// 挪动数据
	int end = L->lenght - 1;
	while (end >= 0)
	{
		L->elem[end + 1] = L->elem[end];
		--end;
	}

	L->elem[0] = x;
	L->lenght++;
}

10、顺序表中删除第i位置的元素

int ListDelete_Sq(Sqlist *L,int i){
        int j;
        if(i<1||i>(L->lenght))return 0;
        for(j=i;j<=L->lenght-1;j++)
                L->elem[j-1]=L->elem[j];
        L->lenght--;
        return 1;
}

11、顺序表中头删和尾删

//尾删
void PopBack(Sqlist* L)
{
	// 温柔的检查
	if (L->lenght == 0)
		return;
	L->elem[L->lenght - 1] = 0;//将删除掉的位置置零
	L->lenght--;
}


//头删
void PopFront(Sqlist* L)
{
	
	// 暴力检查
	assert(psl->lenght > 0);

	int start = 1;
	while (start < L->lenght)
	{
		L->elem[start-1] = L->elem[start];
    	start++;
	}

	L->lenght--;
}

今天的分享就到这啦😉


如果我的文章对您有帮助,

希望可以 “点赞” “收藏” “关注” 一键三连支持一下哦!

想了解更多知识请前往故里♡9513的博客

如果以上内容有什么问题,欢迎留言,大家一起学习,共同进步。


我们下期见😉~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

故里♡9513

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

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

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

打赏作者

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

抵扣说明:

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

余额充值