顺序表

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

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储。
  2. 动态顺序表:使用动态开辟的数组存储。

接口实现:增删查改

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType*_array;//存储空间基地址  也可用数组·
	size_t size;//数据个数
	size_t capacity;//容量
}SeqList;
void SeqListInit(SeqList *ps, size_t _capacity);//初始化
void SeqListDestory(SeqList *ps);//销毁
void CheckCapacity(SeqList *ps);//检查是否需要扩容
void SeqListPushBack(SeqList *ps, SLDataType x);//尾插
void SeqListPopBack(SeqList *ps);//头插
void SeqListPushFort(SeqList *ps, SLDataType x);//尾删
void SeqListPopFort(SeqList *ps);//头删
void SeqListPrint(SeqList *ps);//打印
int SeqListFind(SeqList*ps, SLDataType x);//查找 返回下标
void SeqListInsert(SeqList*ps, size_t pos, SLDataType x);//在指定下标插入元素x
void SeqListErase(SeqList*ps, size_t pos);//删除下标pos的元素

void SeqListBubblesort(SeqList*ps, SLDataType x);//冒泡排序
int SeqListBinaryFind(SeqList*ps, SLDataType x);//二分查找
void SeqListRemoveAll(SeqList*ps, SLDataType x);//删除所有的x 

1.建立结构体

顺序表的存储结构
SLDataType 代表数据类型 可以是int char 等 也可以是struct结构体类型
_array是存储空间的基地址 ,因为顺序表是用地址连续的存储单元来存储,所以只要知道了起始位置就可以访问顺序表中任意数据
capacity表示 存储空间的大小 size表示存储元素个数

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType*_array;//存储空间的基地址
	size_t size;//个数
	size_t capacity;//容量
}SeqList;
2.顺序表初始化和销毁
void SeqListInit(SeqList *ps, size_t capacity)//初始化
{
	assert(ps);//地址ps不能为空
	ps->_array = (SLDataType*)malloc(sizeof(SLDataType)*capacity);
	assert(ps->array);
	ps->capacity = capacity;
	ps->size = 0;
}

void SeqListDestory(SeqList *ps)//销毁
{
	assert(ps);
	if (ps->_array)
	{
		free(ps->_array);
		ps->_array = NULL;
		ps->capacity = ps->size = 0;
	}
}
3.顺序表的扩容

当size == capacity时表示存储空间已满 ,当需要新增元素时需要扩容 ,扩容后大小一般设为原大小的两倍

static void CheckCapacity(SeqList *ps)//检查容量
{
	//用realloc函数扩容
	//assert(ps);
	//if (ps->size==ps->capacity)
	//{
	//	ps->capacity *= 2;
	//	ps->_array = (SLDataType*)realloc(ps->_array, ps->capacity*sizeof(SLDataType));
	//	assert(ps->_array);
	//}
	
	assert(ps);
	int newcapacity = 2 * ps->capacity;
	SLDataType*newArray = (SLDataType*)malloc(sizeof(SLDataType)*newcapacity)//申请信的存储空间 大小为原来的二倍
	assert(newArray);
	for (int i = 0; i < ps->size; i++)
	{
		newArray[i] = ps->_array[i];//将原空间内容复制到新空间
	}
	free(ps->_array);//释放原空间
	ps->_array = newArray;//指向新空间 
	ps->capacity = newcapacity;//新空间大小
}
4.增删查改

在增加元素时都需要进行判断是否需要扩容

void SeqListPushBack(SeqList *ps, SLDataType x)//尾插
{
	assert(ps);
	CheckCapacity(ps);//检查是否需要扩容 时间复杂度为O(n)
	ps->_array[ps->size] = x;
	ps->size++;
}
void SeqListPopBack(SeqList *ps)//尾删 复杂度为o(1)
{
	assert(ps&&ps->size);
	ps->size--;
}
void SeqListPushFort(SeqList *ps, SLDataType x)//头插  时间复杂度为o(n)
{
	assert(ps);
	CheckCapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->_array[i] = ps->_array[i - 1];
	}
	ps->_array[0] = x;
	ps->size++;
}
void SeqListPopFort(SeqList *ps)//头删
{
	int left = 0;
	int right = ps->size - 1;
	assert(ps);
	while (left < right)
	{
		ps->_array[left] = ps->_array[left + 1];
		left++;
	}
	ps->size--;
}
int SeqListFind(SeqList*ps, SLDataType x)//遍历查找 返回位数
{
	int i = 0;
	assert(ps);
	for (i = 0; i < ps->size; i++)
	{
		if (x == ps->_array[i])
		{
			return i+1;
		}
	}
	return -1;
}
void SeqListInsert(SeqList*ps, size_t pos, SLDataType x)//在当pos位置插入
{
	assert(ps != NULL);
	assert(pos > 0 && pos <= ps->size);
	CheckCapacity(ps);
	int i = ps->size;
	for (; i <= pos; i--)
	{
		ps->_array[i] = ps->_array[i - 1];
	}
	ps->_array[i - 1] = x;
	ps->size++;
}
void SeqListErase(SeqList*ps, size_t pos)//在pos位置删除
{
	assert(ps!=NULL);
	assert(pos > 0 && pos <= ps->size);
	for (int i = pos - 1; i < ps->size - 1; i++)
	{
		ps->_array[i] = ps->_array[i + 1];
	}
	ps->size--;
}

void SeqListErase(SeqList*ps, size_t pos)//在当前位置删除
{
	assert(ps!=NULL);
	assert(pos > 0 && pos <= ps->size);
	for (int i = pos - 1; i < ps->size - 1; i++)
	{
		ps->_array[i] = ps->_array[i + 1];
	}
	ps->size--;
}
5.删除顺序表中所有元素x 要求空间复杂度为O1 时间复杂度为On
void SeqListRemoveAll(SeqList*ps, SLDataType x)//删除当前以后的所有值
{/*
	int i = 0;
	assert(ps);
	for (i = 0; i < ps->size; i++)
	{
		if (ps->_array[i] == x)
		{
			SeqListErase(ps, x);
			i--;
		}
	}
*/
	//时间复杂度为n 空间复杂度为1
	int i, j;
	for (i = 0, j = 0; i < ps->size; i++)
	{
		if (ps->_array[i] != x)
		{
			ps->_array[j] = ps->_array[i];
			j++;
		}
	}
	ps->size = j;
}
6.顺序表的冒泡排序和二分查找
void SeqListBubblesort(SeqList*ps, SLDataType x)//冒泡排序
{
	int i = 0;
	int end =  ps->size - 1;
	assert(ps);
	while (end >= 0)
	{
		for (i = 0; i < end; i++)
		{
			if (ps->_array[i]>ps->_array[i + 1])
			{
				SLDataType tmp = ps->_array[i];
				ps->_array[i] = ps->_array[i + 1];
				ps->_array[i + 1] = tmp;
			}
		}
		end--;
	}
}

int SeqListBinaryFind(SeqList*ps, SLDataType x)//二分查找
{
	int start = 0;
	int end = ps->size;
	int mid = 0;
	while (start < end)
	{
		mid = (start + mid) / 2;
		if (ps->_array[mid]==x)
		{
			return mid;
		}
		else if (ps->_array[mid]>x)
		{
			end = mid - 1;
		}
		else
		{
			start = mid + 1;
		}
	}
	return -1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值