数据结构入门——顺序表

目录

定义

基本操作

顺序表的初始化

增加元素

头插法进行元素扩展

尾插法进行元素扩展

指定位置插入元素

删除元素

在头部进行删除元素

在尾部进行删除元素

删除指定位置元素

改变相应位置元素

查找固定值

总结


定义

顺序表是存储相同数据元素的有序序列。

顺序表定义分为静态顺序表和动态顺序表:

1)、静态顺序表在定义时就规定了能存储的数据的大小,会造成空间不够或者空间利用率不足的问题

2)、动态顺序表则可很好的避免这个问题

#include<stdio.h>
#include<stdlib.h>

#define N 10
typedef int SLDataType;

静态的顺序表
struct SeqList
{
	SLDataType a[N];
	int size;
};


//动态的顺序表
typedef struct SeqList
{
	SLDataType* a;
	int size;  //存储的有效数据的个数
	int capacity;  //容量
}SL;

基本操作

顺序表的初始化

初始化就是给顺序表申请空间,并对初始容量进行定义。用malloc进行动态内存申请。

void SLInit(SL *psl)
{
	psl->a = malloc(sizeof(SLDataType)*4);
	if (psl->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	psl->capacity = 4;
	psl->size = 0;
}

增加元素

头插法进行元素扩展

在插入前都要对指针进行断言,防止野指针问题,并且在进行插入前要判断当前申请的空间够不够插入,若是不够插入要进行realloc重新申请更大的空间,并将psl->a指向刚才申请的空间,然后更改顺序表的容量。

void SLCheckCapacity(SL* psl)
{
	assert(psl);
	if (psl->size == psl->capacity)
	{
		SLDataType* temp = realloc(psl->a, sizeof(SLDataType) * psl->capacity * 2);//扩容到二倍
		if (temp == NULL)
		{
			perror("realloc fail");
			return;
		}
		psl->a = temp;
		psl->capacity *= 2;
	}
}

头部插入是将元素整体进行后移操作,用循环可解决这个问题,最后将0号位置的元素设置成要插入的元素即可。

void SLPushFront(SL* psl, SLDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;
	psl->size++;
}

尾插法进行元素扩展

尾插是将要插入的元素每次插入在顺序表的最后,同样的在插入元素之前要进行assert(psl)断言检查空指针问题,也是要检查顺序表的容量是否够插入元素,不够插入元素就进行扩展。最后将psl->size位置的元素设置为要插入的元素。最后更改psl->size加一

void SLPushBack(SL* psl, SLDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);
	psl->a[psl->size++] = x;
}

指定位置插入元素

在指定位置插入元素也是元素进行移动,在插入前也是要进行断言,并且要判断插入位置是否合法,检查当前顺序表的容量。

插入的本质就是元素的移动,将pos位置后的元素整体的后移,最后设置pos位置的值为要插入的值然后更改size即可。

void SLInsert(SL* psl, int pos, SLDataType x)
{
	/*if (pos<0 || pos>psl->size)
		return;*/
	assert(psl);
	assert(0 <= pos && pos <= psl->size);//其表达式值为假时终止程序
	SLCheckCapacity(psl);
	/*int end = psl->size;
	while (end > pos-1 )
	{
		psl->a[end] = psl->a[end - 1];
		end--;
	}
	psl->a[pos-1] = x;*/

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

 

删除元素

在头部进行删除元素

删除元素的本质也是进行元素的移动,将第一个元素之后的元素整体进行前移并修改size的值即可。

在删除元素之前要进行assert(psl)和assert(psl->size>0)的断言。防止空指针和空顺序表的问题。

void SLPopFront(SL* psl)
{
	assert(psl);
	/*if (psl->size == 0)
		return;*/
	/*int i = 0;
	for ( i = 0; i < psl->size-1; i++)
	{
		psl->a[i] = psl->a[i + 1];
	}*/

	assert(psl->size > 0);
	int start = 0;
	while (start < psl->size - 1)
	{
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	psl->size--;
}

在尾部进行删除元素

在删除元素之前要进行assert(psl)和assert(psl->size>0)的断言。防止空指针和空顺序表的问题。

尾删不需要移动元素,只需要修改size的值即可。

void SLPopBack(SL* psl)
{
	assert(psl);
	//暴力检查
	assert(psl->size > 0);
	if (psl->size > 0)
		psl->size--;
}

删除指定位置元素

删除元素的本质也是进行元素的移动,将要删除元素之后的元素整体进行前移并修改size的值即可。

在删除元素之前要进行assert(psl)和assert(psl->size>0)的断言。防止空指针和空顺序表的问题。

void SLErase(SL* psl, int pos)
{
	assert(psl);
	assert(0 <= pos && pos < psl->size);//其表达式值为假时终止程序
	SLCheckCapacity(psl);
	int start = pos;
	while (start < psl->size - 1)
	{
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	psl->size--;
}

 

改变相应位置元素

顺序表基于数组进行存储,在修改时用下标进行修改即可

void SLModify(SL* psl, int pos, SLDataType x)
{
	assert(psl);
	assert(0 <= pos && pos < psl->size);
	psl->a[pos] = x;
}

 

查找固定值

查找指定元素的位置,查找成功返回对应元素下标,查找失败返回-1。

int SLFind(SL* psl, SLDataType x)
{
	assert(psl);
	int i = 0;
	for ( i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
			return i;
	}
	return -1;
}

 

总结

顺序表的操作都是基于数组进行,只要理解了数组的工作原理,对顺序表的操作就没有问题! 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值