【C语言】--数据结构--顺序表

目录

1.线性表

2.顺序表

    2.1 静态顺序表

    2.2 动态顺序表

3.顺序表实践功能

4.单链表的实现

    4.1   对数据的初始化

    4.2   输出数据 

    4.3   动态管理进行开辟

    4.4   从起始点输入数据(头插)

    4.5   从尾部输入数据(尾插)

    4.6   从尾部删除数据(尾删)

    4.7   从头部删除数据(头删)

    4.8   查找数据,返回其下标(没有就返回-1)

    4.9   向前插入数据(前插)

    4.10 删除数据 


1.线性表

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

2.顺序表

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

顺序表一般可以分为:         1. 静态顺序表          2. 动态顺序表
          静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间
大小。

    2.1 静态顺序表

            使用定长数组存储元素。

//顺序表的静态存储

#define N 12
typedef int SeqListType;
typedef struct SeqList
{
	SeqListType array[N];	//定长数据
	size_t size;	//有效数据的长度
}SeqList;

    2.2 动态顺序表

            使用动态开辟的数组存储。  

//循序表的动态存储

typedef int SLdatetype;
typedef struct Seqlist
{
	SLdatetype* a;	//指向动态开辟的数组
	size_t size;	//有效的数据个数
	size_t capacity;	//容量空间的大小
}SL;

3.顺序表实践功能

        静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空 间开多了浪费,开少了不够用。

typedef int SLdatetype;

typedef struct Seqlist
{
	SLdatetype* a;	//指向动态开辟的数组
	size_t size;	//有效的数据个数
	size_t capacity;	//容量空间的大小
}SL;

//对数据的初始化
void SeqlistInit(SL* s1);
//输出数据
void SLPrint(SL* s1);
//从起始点输入数据(头插)
void SLPushFront(SL* s1, SLdatetype n);
//从尾部输入数据(尾插)
void SLPushBack(SL* sl, SLdatetype n);
//从尾部删除数据(尾删)
void SLPopBack(SL* sl);
//从头部删除数据(头删)
void SLPopFront(SL* sl);
//查找数据,返回其下标(没有就返回-1)
int SLFind(SL* sl, SLdatetype n);
//向前插入数据(前插)
void SLInsert(SL* sl, int pos, SLdatetype n);
//删除数据
void SLErase(SL* sl, int pos);

4.单链表的实现

    4.1 对数据的初始化

//对数据的初始化
void SeqlistInit(SL* s1)
{
	assert(s1);

	s1->a = NULL;
	s1->size = s1->capacity = 0;
}

    4.2 输出数据 

//输出数据
void SLPrint(SL* sl)
{
	assert(sl);
	int i = 0;
	for (i = 0; i < sl->size; i++)
	{
		printf("%d ", sl->a[i]);
	}
	printf("\n");
}

    4.3 动态管理进行开辟

          在插入数据函数中需要引用,当空间不够时开辟空间。

//动态管理进行开辟
void SLCheckCapacity(SL* sl)
{
	assert(sl);
	if (sl->size == sl->capacity)
	{
		int newCapacity = sl->capacity == 0 ? 4 : sl->capacity * 2;
		sl->a = (SLdatetype*)realloc(sl->a, newCapacity * sizeof(SL));
		assert(sl->a);

		sl->capacity = newCapacity;
	}
}

    4.4 从起始点输入数据(头插)

        我们需要注意size与数据的关系:

//从起始点输入数据(头插)
void SLPushFront(SL* sl)
{
	//如果空间小了,就用动态管理进行开辟
	SLCheckCapacity(sl);

	//挪动数据
	int end = sl->size - 1;
	while (end >= 0)
	{
		sl->a[end + 1] = sl->a[end];
		--end;
	}
	sl->a[0] = n;
	sl->size++;
}

        由于,我们是要进行头插,所以我们需要将a[0]腾出来。

        最终,再将我们所需要插入的数值(N)放入a[0]中,再将size+1。

    4.5 从尾部输入数据(尾插)

//从尾部输入数据(尾插)
void SLPushBack(SL* sl)
{
	SLCheckCapacity(sl);

	assert(sl);
	sl->a[sl->size] = n;
	sl->size++;
}

     4.6 从尾部删除数据(尾删)

        这里只需要注意,我们的顺序表是否有数据可以用来删除。赋不赋值不重要,重要的时要size--。

//从尾部删除数据(尾删)
void SLPopBack(SL* sl)
{
	assert(sl != NULL);

	sl->a[ps->size - 1] = 0;
	if (sl->size == 0)
	{
		printf("SeqList is empty\n");
		return;
	}
    sl->size--;
}

    4.7 从头部删除数据(头删)

//从头部删除数据(头删)
void SLPopFront(SL* sl)
{
	assert(sl);
	assert(sl->size > 0);

	int begin = 1;
	while (begin < sl->size)
	{
		sl->a[begin - 1] = sl->a[begin];
		begin++;
	}

	sl->size--;
}

    4.8 查找数据,返回其下标(没有就返回-1)

//查找数据,返回其下标(没有就返回-1)
int SLFind(SL* sl, SLdatetype n)
{
	assert(sl);

	int i = 0;
	for (i = 0; i < sl->size; i++)
	{
		if (n == sl->a[i])
			return i;
	}
	return -1;
}

    4.9 向前插入数据(前插)

        我们需要一个(4.8 查找数据,返回其下标(没有就返回-1))SLFind函数。

        同样的道理,顺序表是连续的,所以我们当向前插入数据的同时是要通过向后移动数据,给新插入的数据腾位置。

//向前插入数据(前插)
void SLInsert(SL* sl, int pos, SLdatetype n)
{
	assert(sl);
	assert(pos >= 0 && pos <= sl->size);

	//如果空间小了,就用动态管理进行开辟
	SLCheckCapacity(sl);

	int end = sl->size - 1;
	while (end >= pos)
	{
		sl->a[end + 1] = sl->a[end];
		end--;
	}
	sl->a[pos] = n;
	sl->size++;
}

    4.10 删除数据 

        我们需要一个(4.8 查找数据,返回其下标(没有就返回-1))SLFind函数。

        同样的道理,顺序表是连续的,所以我们当向前插入数据的同时是要通过向前移动数据,将我们所使用的空间归还。

//删除数据
void SLErase(SL* sl, int pos)
{
	assert(sl);
	assert(pos >= 0 && pos <= sl->size);

	int end = sl->size - 1;
	while (pos < end)
	{
		sl->a[pos] = sl->a[pos + 1];
		pos++;
	}
	sl->size--;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

川入

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

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

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

打赏作者

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

抵扣说明:

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

余额充值