数据结构 --- 线性表

引言

无论网上还是课本上对于线性表的定义都是官方且笼统,

而刚刚学习的同学由于知识储备的欠缺,无法很快理解到线性表的本质,

这篇文章会由浅到深讲解线性表,

希望由笔者的一些引导帮助刚刚接触编程的同学


线性表

线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。(这个定义是网上和书本上很常见的定义,但很多初次接触线性表的同学肯定是一头雾水!!)

而我们需要在官方定义上加上自己的理解。


内存

首先:我们都知道数据是储存在电脑的内存中,而电脑的内存我们可以理解是一块无限线性的单元格。

如下图所示:

但是我们无法直接对储存在内存中的数据进行很好的管理,这时候线性表就出现了。

线性表定义中的  “数据元素的有限序列”,是指人为指定开辟一段空间为我们使用,是不可控的内

实现了可控化。

根据是否可以随着需要的变化,改变提前开辟的内存的大小,把线性表分为静态和动态线性表。


静态线性表

静态线性表是以数组为主,提前申请一段空间,这段空间在程序运行时不可改变大小。

#define Capacity 10     //表示线性表的最大容量
typedef struct
{
	int data[Capacity];  //数组存放数据元素 
	int size;            //表示数组中储存了多少数据 
}SqList;

上面是静态线性表的C语言实现方式,Capacity 10, 代表了这次线性表一次只能存储10个数据。

size 表示了当前有多少个数据。只要size<Capacity 说明这段线性表还有空间可以储存数据。

下面是初始化线性表:

void SeqListInit1(Seqlist* ps) //初始化线性表
{
	for (int i = 0; i < Capacity; i++)
	{
		ps->data[i] = 0; //将所有元素赋值为0
	}
	ps->size = 0; //已存数据为0
}

上面代码完成了线性表的初始化,数组元素为0,数组已存数据为0;

下面实现数据的插入:

void SeqListPushBack(SL* ps, int x) //从头开始插入数据
{
	if (ps->size < Capacity)
	{
		ps->data[ps->size] = x;
        ps->size++;
	}
	else
	{
		printf("The capacity of SeqList is insufficient");
		exit(0);
	}
}

if (ps->size < Capacity),判断是否还有空间容量,放入数据。

下面实现了线性表的数据删除:

void SeqListPopDelete(SL* ps) //从头开始删除数据
{
	int begin = 0;
	while (begin < ps->size)
	{
		ps->data[begin] = ps->data[begin + 1];
		begin++;
	}
	ps->data[begin-1] = 0;
}

从头部开始删除数据,之后将数组中的所以数据,向前移动一位。

上面完成了静态线性表的基本操作(初始化、添加、删除数据),但是会发现静态线性表具有很大的

一旦数据总量超过了数据的大小,则将无法添加数据。

而动态线性表弥补了静态线性表的上述缺点。


动态线性表

动态线性表和动态线性表的最大不同点,在于定义结构体的时候,用指针代替了数组。

动态线性表的定义:

typedef struct Seqlist
{
	int* List;
	int size;     //表示数组中储存了多少数据
	int capacity; //数据的容量 
}SL;

动态线性表主要由三个要素组成,

指针(List):用于线性表中数据的检索;

size:表示线性表中有效数据的个数;

capacity:表示线性表容量。

而动态线性表的 “动态”体现在什么地方呢? “动态” 体现在根据数据个数的变化,通过relloc 函数增

加线性表的容量。

对动态线性表的初始化:

void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

对于动态线性表,给定一段初始的空间

void SeqListChackCapacity(SL* ps)
{
	//判断容量是否为0
	if (ps->size == ps->capacity)
	{
		//三目运算符,如果==0,赋值4,
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//分配ps->capacity个空间
		int* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(int));
		if (NULL == tmp)
		{
			printf("realloc failed\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;

	}

在分配容量之前,需要判断线性表是否还有有效空间,否则需要对线性表进行原容量两倍扩容,

这就是动态线性表相对了静态线性表的高明之处了,只要线性表容量满了,则会自动对原容量进

行两倍的扩容,完美的解决了容量不足的问题! 

添加数据

//添加数据
void SeqListPushBack(SL* ps, int x)
{
	SeqListChackCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

添加数据之前需要判断线性表是否需要扩容,将 数据 x 添加到线性表中,每次添加一个数据,线

性表的有效数据+1;

 删除数据

//从尾部删除数据
void DeletList(SL* ps)
{
	if (ps->size > 0)
	{
		ps->size--;
	}
}

线性表的删除数据就显得比较容易了,将有效数据-1,则完成了数据的删除。

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值