数据结构之顺序表——王道

文章目录

一.线性表的定义(逻辑结构)和基本操作(运算)

由绪论知,

学习一个具体的数据结构时需关注数据结构的:

  1. 逻辑结构(数据元素 之间存在的逻辑关系线性结构和非线性结构,线性结构如队列、链表等,非线性结构如树、图)
  2. 物理结构(存储结构)(逻辑结构用计算机语言的实现 ,包括顺序存储,链式存储,索引存储和散列存储
  3. 数据的运算
    用不同存储结构 实现线性表不同
    线性表: 大白话:数据被一条线串在一起
    相同 数据类型的n个数据元素的有限 序列。

    线性表的创销、增删改查
    改之前要查
    InitList(&L):初始化表,构造一个空的线性表L,分配内存空间。
    DestroyList(&L):销毁线性表,释放线性表L所占的内存空间。
    ListInsert(&L,i,e):插入操作,在第i个位置上插入元素e
    ListDelete(&L,i,&e):删除操作,删除表L中第i个位置的元素,并用e返回删除元素的值。
    LocateElem(L,e):按值查找
    GetElem(L,i)按位查找
  • 这些接口具有抽象性,一般函数定义为<返回值类型>函数名(<参数1类型> 参数1,······),因为这些元素可以存储各种类型变量
  • 函数名,参数名等都可以变
  • &:把参数的修改结构带回来
  • 位序从1开始,程序下标从0开始

二.顺序表的定义

线性表------用顺序存储 的方式实现线性表

顺序存储:把逻辑 上相邻的元素存储在物理 位置也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。

如何知道数据元素大小?

答:sizeof(ElemType)

c 复制代码
tyepedef struct{
	int num;
	int people;
}Customer;

sizeof(Customer):8B

下面顺序表实现方式:静态分配

cpp 复制代码
#define int N 10
typedef int ElemType;
typedef struct{
	ElemType a[N];//用静态数组存放数据元素
	int length;//顺序表当前长度
}Customer;

给各个空间分配连续存储空间,大小:N*sizeof(ElemType)

cpp 复制代码
//定义顺序表
#include <stdio.h>
#typedef MaxSize 10
typedef int ElemType;
typedef struct
{
	ElemType a[MaxSize];
	int length;//顺序表当前长度
}SqList;
//初始化顺序表
void InitList(SqList &L){//用SqList定义顺序表L
	for(int i=0;i<MaxSize;i++)
		L.data[i]=0;//初始化i中的所有数据元素,可省略
	L.length=0;//长度初始化为0
}
int main(){
	SqList L;//声明一个顺序表
	InitList(L);//初始化顺序表
	return 0;
}

静态分配有局限性,可动态分配

cpp 复制代码
#define InitList 10//初始长度为10
typedef struct
{
	ElemType*a;//动态分配数组的指针
	int MaxSize;//最大数组长度
	int length;//当前数组长度
}SqList;
	 

动态申请和释放空间在C语言中有malloc和free

cpp 复制代码
L.data=(ElemType*)malloc(sizeof(ElemType)* InitSize);

因为存储空间存储数据元素 ,因此需要把malloc申请的空间强转ElemType类型 指针。

InitSIze为malloc函数的参数,指明要分配多少连续空间

malloc和free包含在#include<stdlib.h>文件中

三.顺序表的插入删除

1.插入操作

ListInsert(&L,i,e);在线性表L第i个位置上插入指定元素e

顺序表长度:5,b的后驱结点,d的前驱节点

基于静态顺序表实现

cpp 复制代码
#include <stdio.h>
#typedef MaxSize 10
typedef int ElemType

typedef struct
{
	ElemType data[MaxSize];
	int length;
}SqList;

void InitList(SqList &L)
{
	L.length=0;//在L数组上所以都要加L.
}

void InsertList(SqList &L,int i,int e){
	if(i<1||i>L.length+1||L.length>=MaxSize)//要有健壮性
	{
		return false;//插入失败
	}
	//for(int a=i-1;a<MaxSize:a++)
	//错误,应该从最后一个往后移,否则会被覆盖
	for(int a=L.length;a>=i;a--)
	{
		L.data[a+1]=L.data[a];//记得加L,因为是数组
	}
	data[i-1]=e;//i是位序
	length++;
	return true;//插入成功
}

int main()
{
	SqList(&L);
	InitList(L);
	//省略一些代码,插入数据
	InsertList(&L,3,7);
	return 0;
}//O(n)时间复杂度,n=L.length

2.顺序表的删除

DeleteList(&L,i,&e):在线性表L中的第i个位置,并用e返回删除元素的值。

cpp 复制代码
void DeleteList(SqList &L,int i,int* e)
{
	if(i<1||i>L.length)
		return false;
	//L.data[i-1]=e;//应该把值赋给e
	 e=L.data[i-1];
	for(int j=i;j<L.length;j++)//j<L.length
	{
		L.data[j]=L.data[j+1];
	}
	L.length--;//记得把L.Length的值-1
	return true;
}
int main()
{
	SqList(&L);
	InitList(L);
	int e=-1;//用变量e把删除的元素带回来
	//插入一些数据
	if(DeleteList(L,3,e))
		printf("已删除第3个位置的值,值为%d\n",e);
	else
		printf("不合法,无法删除");
	return 0;
}//时间复杂度:O(n)

定义的的删除操作e的变量是引用 类型的&e

所以这里的e和main函数里定义的e在内存中对应的是同一份数据

注意

  • 更改length的值
  • 删除的是数组下标还是位序
  • 代码要有健壮性

四.顺序表的查找

代码实现与时间复杂度分析:

  1. 按位查找
  2. 按值查找

1.按位查找

GetElem(L,i):在顺序表L中查找第i个位置的元素的值

1.1静态分配

cpp 复制代码
Elemtype GetElem(SqList L,int i) 
{
	//判断i的值是否合法
	return L.data[i-1];//直接返回第i-1个位置的值
}

1.2动态分配

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#typedef InitSize 10//定义初始长度10
typedef int ElemType;
typedef struct
{
	ElemType* data;//动态分配数组的指针
	int MaxSize;//当前能容纳的最大数组
	int length;//占用的数组长度
}SqList;

void InitList(SqList &L)
{
	//用malloc申请一片连续空间
	ElemType* data=(ElemType*)malloc(InitSize*sizeof(ElemType);
	L.MaxSize=InitSize;
	L.length=0;
}

ElemType GetElem(SqList L,int i)
{
	int n=0;
	L.MaxSize=(ElemType*)malloc(sizeof(ElemType)*n);
	return a[i-1];
}
时间复杂度:O(1)	 

表示每个数组下标对应哪几个数组的数据,与指针类型有关

符合顺序表随机存储的特性,因为顺序表的所有数据连续存放,且数据类型相同,所占空间一样大

2.按值查找

LocateElem(L,e); 在L中查找具有给定元素关键字值的元素。如果能找到,返回元素所在的存放位置

cpp 复制代码
ElemType LocateElem(SqList L,ElemType e)
{
	for(int i=0;i<L.length;i++)
		if(L.data[i]==e)
			return i-1;
		return 0;//退出循环,表明查找失败
}时间复杂度:O(n)

结构类型不能直接用==判断两个结构体是否相等,需要依次对比各个结构体的分量是否相等

cpp 复制代码
bool Custom(Customer a,Cumstomer b)
{
	if(a.num==b.num && a.people==b.people)
		return true;
	else
		return false;
}
相关推荐
搬砖的小码农_Sky3 小时前
C语言:数组
c语言·数据结构
先鱼鲨生5 小时前
数据结构——栈、队列
数据结构
一念之坤5 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年5 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王5 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
liujjjiyun6 小时前
小R的随机播放顺序
数据结构·c++·算法
Reese_Cool7 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
djk88888 小时前
.net将List<实体1>的数据转到List<实体2>
数据结构·list·.net
搬砖的小码农_Sky8 小时前
C语言:结构体
c语言·数据结构
_OLi_10 小时前
力扣 LeetCode 106. 从中序与后序遍历序列构造二叉树(Day9:二叉树)
数据结构·算法·leetcode