【数据结构】1.顺序表

目录

顺序表

1.顺序表的概念及结构

2.特点

3.动态顺序表的实现

   3.1 顺序表初始化

   3.2 顺序表销毁

   3.3 顺序表打印

   3.4 检查空间,如果满了,进行增容

   3.5 顺序表尾插

   3.6 顺序表尾删

   3.7 顺序表头插

   3.8 顺序表头删

   3.9 顺序表查找

   3.10 顺序表在pos位置插入x

   3.11 顺序表删除pos位置的值

   3.11 冒泡排序

   3.12 二分查找

 

顺序表

1.顺序表的概念及结构

顺序表一般可分为:

1.静态顺序表:使用定长数组存储

2.动态顺序表:使用动态开辟的数组存储

// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
 SLDataType array[N]; // 定长数组
 size_t size; // 有效数据的个数 
}SeqList;

 

// 顺序表的动态存储
typedef struct SeqList
{
 SLDataType* array; // 指向动态开辟的数组
 size_t size ; // 有效数据个数
 size_t capicity ; // 容量空间的大小
}SeqList;

2.特点

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

3.动态顺序表的实现

// 顺序表的动态存储
typedef struct SeqList
{
 SLDataType* array; // 指向动态开辟的数组
 size_t size ; // 有效数据个数
 size_t capicity ; // 容量空间的大小
}SeqList;

// 基本增删查改接口

// 顺序表初始化
void SeqListInit(SeqList* psl, size_t capacity);

// 顺序表销毁
void SeqListDestory(SeqList* psl);

// 顺序表打印
void SeqListPrint(SeqList* psl);

// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);

// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);

// 顺序表尾删
void SeqListPopBack(SeqList* psl);

// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);

// 顺序表头删
void SeqListPopFront(SeqList* psl);

// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);

// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);

// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);

3.1 顺序表初始化

void SeqListInit(SeqList* ps);

void SeqListInit(SeqList* ps)//初始化
{

	assert(ps);
	ps->_a = NULL;
	ps->_size = 0;
	ps->_capacity = 0;
}

 

3.2 顺序表销毁

void SeqListDestory(SeqList* ps);

void SeqListDestory(SeqList* ps)//销毁空间
{
	free(ps->_a);
	ps->_a = NULL;
	ps->_size = 0;
	ps->_capacity = 0;
}

 

3.3 顺序表打印

void SeqListPrint(SeqList* ps);

void SeqListPrint(SeqList* ps)//打印
{
	assert(ps);
	for (size_t i = 0; i < ps->_size; ++i)
	{
		printf("%d ", ps->_a[i]);
	}
	printf("\n");
}

3.4 检查空间,如果满了,进行增容

void CheckCapacity(SeqList* ps);

void SeqListCheckCapacity(SeqList* ps)//检查空间,如果满了,进行增容
{

	if (ps->_size == ps->_capacity)
	{
		size_t newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
		                                // == 0 赋值4 不等于0 执行后面的*2
		ps->_a = realloc(ps->_a, newcapacity * sizeof(SLDataType));
		//realloc(要调整的内存地址,调整后的大小——要字节数)空间扩容
		ps->_capacity = newcapacity;
	}

}

3.5 顺序表尾插

void SeqListPushBack(SeqList* ps, SLDataType x);

void SeqListPushBack(SeqList* ps, SLDataType x) //尾插
{
	assert(ps);
	SeqListCheckCapacity(ps);
	ps->_a[ps->_size] = x;//size代表数组下标表示的是最后一个位置的下一个位置
	ps->_size++;			

}

3.6 顺序表尾删

void SeqListPopBack(SeqList* ps);

void SeqListPopBack(SeqList* ps)  //尾删
{
	assert(ps && ps->_size > 0);
	//ps->_a[ps->_size - 1] = 0;//数据的个数比数组下标数值多一
	ps->_size--;

}

3.7 顺序表头插

void SeqListPushFront(SeqList* ps, SLDataType x);

void SeqListPushFront(SeqList* ps, SLDataType x) //头插
{
	assert(ps);
	SeqListCheckCapacity(ps);//空间扩容
	//挪动数据  从后往前挪
	int end = ps->_size - 1; //这里为什么定义size-1呢 因为end代表数组下标 并非元素个数
	for ( ; end >= 0; --end)
	{
		ps->_a[end + 1] = ps->_a[end];  //前面的给后面的赋值 一次往后移动
	}
	ps->_a[0] = x;
	ps->_size++;//插入一个数据的同时要增加size个数


}

3.8 顺序表头删

void SeqListPopFront(SeqList* ps);

void SeqListPopFront(SeqList* ps)  //头删
{
	assert(ps && ps->_size > 0);

	for (size_t start = 0; start <= ps->_size - 1; ++start)
	{
		ps->_a[start] = ps->_a[start + 1];
	}

	ps->_size--;
}

3.9 顺序表查找

int SeqListFind(SeqList* ps, SLDataType x);

int  SeqListFind(SeqList*ps, SLDataType x)//查找
{
	assert(ps);
	for (size_t i = 0; i <= ps->_size-1; ++i)
	{
		if (ps->_a[i] == x)
		{
			return i;
		}

	}
	return -1;

}

3.10 顺序表在pos位置插入x

void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);

void SeqListInsert(SeqList*ps, size_t pos, SLDataType x)//插入 其中pos表示插入的位置
{
	assert(ps && pos < ps->_size);
	SeqListCheckCapacity(ps);
	int  end = ps->_size ;  

	while (end >= (int)pos)//防止隐式类型转换
	{
		ps->_a[end] = ps->_a[end - 1];
		--end;
	}
	ps->_a[pos] = x;
	ps->_size++;
}

 

3.11 顺序表删除pos位置的值

void SeqListErase(SeqList* psl, size_t pos);

void SeqListErase(SeqList*ps, size_t pos)//删除

{
	assert(ps && pos < ps->_size);
	size_t i = pos + 1;
	while (i <= ps->_size - 1)
	{
		ps->_a[i - 1] = ps->_a[i];
		++i;
	}

	ps->_size--;


}

3.11 冒泡排序

void SeqListBubbleSoet(SeqList* ps)

void SeqListBubbleSoet(SeqList* ps)//冒泡排序
{
	 //控制冒泡的终止位置
	 for (size_t end = ps->_size; end > 0; --end)
	 {
		 int exchange = 0;
		 //单趟冒泡
		 for (size_t i = 0; i < end - 1; i++)//注意起始位置与终止位置
		 {
			 if (ps->_a[i] > ps->_a[i + 1])
			 {
				 SLDataType tmp = ps->_a[i];
				 ps->_a[i] = ps->_a[i + 1];
				 ps->_a[i + 1] = tmp;

				 exchange = 1;
			 }
		 }
		 if (exchange == 0)
		 {
			 break;
		 }
	 }
}

3.12 二分查找

int  SeqListBinaryFind(SeqList* ps, SLDataType x)

int  SeqListBinaryFind(SeqList* ps, SLDataType x) //二分查找
 {
	 size_t begin = 0, end = ps->_size-1;
	 while (begin <= end )
	 {
		 size_t mid = (begin + end) / 2;
		 if (ps->_a[mid] == x)
		 {
			 return mid;
		 }
		 else if (ps->_a[mid] < x)
		 {
			 begin = mid + 1;
		 }
		 else
		 {
			 end = mid - 1;
		 }
	 }
	 return -1;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值