数据结构--顺序表专题(C语言实现)


一、顺序表

顺序表是一种线性数据结构,它采用一段连续的内存空间来存储元素。顺序表中的元素按照一定的顺序排列,可以通过下标访问和修改元素。

顺序表的定义通常包含以下几个要素:

  1. 内存空间:顺序表需要一段连续的内存空间来存储元素。
  2. 元素个数:顺序表中元素的数量,也即顺序表的长度。
  3. 元素类型:顺序表可以存储不同类型的元素,如整数、浮点数、字符等。
  4. 元素存储方式:顺序表中元素存储的方式可以是顺序存储或链式存储。顺序存储是指将元素依次存放在内存空间中的连续位置,而链式存储则是通过指针相连的方式来存储元素。

顺序表可以通过下标访问和修改元素,具有随机访问的特点,但插入和删除元素时需要移动大量元素,时间复杂度较高。

二、分类

1.静态顺序表

代码如下(示例):

struct Seqlist
{
    int arr[100];//定长数组
    int size;//记录顺序表当前有效的数据个数
 };

2.动态顺序表

代码如下(示例):

struct Seqlist
{
    int* arr;
    int size;//记录顺序表当前有效的数据个数
    int capacity;//记录顺序表当前的空间大小
 };

三.代码实现

1.初始化

#include"SeqList.h"
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

2.销毁

void SLDestroy(SL* ps)
{
	if (ps->arr) //等价于  if(ps->arr != NULL)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

3.尾插

void SLPushBack(SL* ps, SLDataType x)
{
	温柔的解决方式
	//if (ps == NULL)
	//{
	//	return;
	//}
	assert(ps); //等价与assert(ps != NULL)

	//ps->arr[ps->size] = x;
	//++ps->size;
	SLCheckCapacity(ps);//扩容
	ps->arr[ps->size++] = x;
}

4.扩容

void SLCheckCapacity(SL* ps)
{
	//插入数据之前先看空间够不够
	if (ps->capacity == ps->size)
	{
		//申请空间
		//malloc calloc realloc  int arr[100] --->增容realloc
		//三目表达式
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);//直接退出程序,不再继续执行
		}
		//空间申请成功
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}

5.头插

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//先让顺序表中已有的数据整体往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//arr[1] = arr[0]
	}
	ps->arr[0] = x;
	ps->size++;
}

6.写一个打印

void SLPrint(SL s)
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ", s.arr[i]);
	}
	printf("\n");
}

7.尾删

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	//顺序表不为空
	//ps->arr[ps->size - 1] = -1;
	--ps->size;
}

8.头删

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);

	//数据整体往前挪动一位
	for (int i = 0; i < ps->size-1 ; i++)
	{
		ps->arr[i] = ps->arr[i + 1]; //arr[size-2] = arr[size-1]
	}
	ps->size--;
}

9.指定位置插入数据

void SLInsert(SL* ps,int pos,SLDataType x)
{
   assert(ps);
   assert(pos>=0&&pos<=ps->size);  
   SLCheckCapacity(ps);
   for(int i=ps->size;i>pos;i--)
   {
    ps->arr[i]=ps->arr[i-1];
   }
    ps->arr[pos]=x;
    ps->size++;
}

10.指定位置删除数据

void SLErase(SL* ps,int pos)
{
   assert(ps);
   assert(pos>=0&&pos<ps->size);  
   for(int i=pos;i<ps->size-1;i++)
   {
    ps->arr[i]=ps->arr[i+1];
   }
    ps->size--;
}

11.查找

int SLFind(SL* ps,SLDatatype x)
{
   assert(ps);
   for(int i=0;i<ps->size;i++)
   {
      if(ps->arr[i]==x)
     {
      return i;//找到了
     }
   }
   return -1;//没有找到
}

亲爱的读者们,非常感谢你们抽出宝贵的时间来阅读我的第一篇博客。我对此感到非常激动和荣幸。希望通过这个平台,我能够与大家分享我的见解和经验,为大家带来一些启发和帮助。谢谢你们的支持与关注,让我们一起开启这段博客之旅吧!
下一次与大家分享顺序表的应用-----通讯录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值