数据结构---顺序表(重点)

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组 上完成数据的增删查改。
顺序表一般可以分为:
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;

头文件SeqList.h

#pragma once
//typedef struct SeqList SeqList;
//typedef struct SeqList* PSeqList;

void SeqListInit(PSeq ps, int capacity);
void SeqListPushBack(PSeq ps, DataType data);
void SeqListPopBack(PSeq ps);
void SeqListPushFront(PSeq ps, DataType data);
void SeqListPopFront(PSeq ps);
void SeqListInsert(PSeq ps, int pos, DataType data);
void SeqListErase(PSeq ps, int pos);
int SeqListFind(PSeq ps, DataType data);
int SeqListEmpty(PSeq ps);
int SeqListSize(PSeq ps);
int SeqListCapacity(PSeq ps);
void SeqListClear(PSeq ps);
void SeqListRemove(PSeq ps, DataType data);
void SeqListDestroy(PSeq ps);
void CheckCapacity(PSeq ps);

//
void TestSeqList();

顺序表初始化

//顺序表初始化
void SeqListInit(PSeq ps, int capacity)
{
	ps->_array = (DataType*)malloc(sizeof(DataType)*capacity);
	if (NULL == ps->_array)
	{
		assert(0);
		return;
	}

	ps->_capacity = capacity;
	ps->_size = 0;
}

头插

//头插
void SeqListPushFront(PSeq ps, DataType data)
{
#if 0
	assert(ps);
	// CheckCapacity(ps);

	// 将顺序表中所有的元素统一向后搬移一个位置
	for (int i = ps->_size - 1; i >= 0; i--)
	{
		ps->_array[i+1] = ps->_array[i];
	}

	// 插入元素
	ps->_array[0] = data;
	ps->_size++;
#endif

	SeqListInsert(ps, 0, data);
}

头删

//头删
void SeqListPopFront(PSeq ps)
{
#if 0
	if (SeqListEmpty(ps))
		return;

	for (int i = 1; i < ps->_size; ++i)
		ps->_array[i-1] = ps->_array[i];

	ps->_size--;
#endif

	SeqListErase(ps, 0);
}

尾插

//尾插
void SeqListPushBack(PSeq ps, DataType data)
{
#if 0
	assert(ps);
	// 顺序表满时需要扩容
	// CheckCapacity(ps);
	ps->_array[ps->_size] = data;
	ps->_size++;
#endif

	SeqListInsert(ps, ps->_size, data);
}

尾删

/尾删
void SeqListPopBack(PSeq ps)
{
#if 0
	assert(ps);
	if (SeqListEmpty(ps))
		return;

	ps->_size--;
#endif

	SeqListErase(ps, ps->_size - 1);
}

指定位置pos插入

//指定位置pos插入
void SeqListInsert(PSeq ps, int pos, DataType data)
{
	assert(ps);
	if (pos < 0 || pos > ps->_size)
		return;

	CheckCapacity(ps);

	for (int i = ps->_size - 1; i >= pos; i--)
		ps->_array[i+1] = ps->_array[i];

	ps->_array[pos] = data;
	ps->_size++;
}

指定位置pos删除

//指定位置pos删除
void SeqListErase(PSeq ps, int pos)
{
	assert(ps);
	if (pos < 0 || pos >= ps->_size)
		return;

	for (int i = pos + 1; i < ps->_size; ++i)
		ps->_array[i-1] = ps->_array[i];

	ps->_size--;
}

查找

//查找
int SeqListFind(PSeq ps, DataType data)
{
	assert(ps);
	for (int i = 0; i < ps->_size; i++)
	{
		if (ps->_array[i] == data)
			return i;
	}
	return -1;
}

移除第一个值为data的元素

// 移除第一个值为data的元素
void SeqListRemove(PSeq ps, DataType data)
{
	SeqListErase(ps, SeqListFind(ps, data));
}

移除所有值为data的元素

/ 移除所有值为data的元素
void SeqListRemoveAll(PSeq ps, DataType data)
{
	assert(ps);
	int count = 0;
	for (int i = 0; i < ps->_size; ++i)
	{
		if (ps->_array[i] == data)
			count++;
		else
			ps->_array[i - count] = ps->_array[i];
	}
}

释放

void SeqListDestroy(PSeq ps)
{
	if (ps->_array)
	{
		free(ps->_array);
		ps->_array = NULL;
		ps->_capacity = 0;
		ps->_size = 0;
	}
}

扩容

void CheckCapacity(PSeq ps)
{
	assert(ps);
	if (ps->_size == ps->_capacity)
	{
		// 顺序表中已经没有空间了
		int newCapacity = ps->_capacity * 2;

		// realloc(p, size)
		// 申请新空间
		int* pTemp = (DataType*)malloc(newCapacity*sizeof(DataType));
		if (NULL == pTemp)
		{
			assert(0);
			return;
		}

		// 拷贝元素 memcpy
		for (int i = 0; i < ps->_size; ++i)
			pTemp[i] = ps->_array[i];

		// 释放旧空间
		free(ps->_array);

		// 更新
		ps->_array = pTemp;
		ps->_capacity = newCapacity;
	}
}

交换数据(函数)

//交换数据(函数)
void Swap(int* pLeft, int* pRight)
{
	int temp = *pLeft;
	*pLeft = *pRight;
	*pRight = temp;
}

打印顺序表

void SeqListPrint(PSeq ps)
{
	for (int i = 0; i < ps->_size; ++i)
		printf("%d ", ps->_array[i]);
	printf("\n");
}

冒泡排序

oid BubbleSort(PSeq ps)
{
	// N---->N-1
	for (int i = 0; i < ps->_size - 1; ++i) // 控制冒泡总的趟数
	{
		int Ischange = 0;
		// 冒泡的具体方式:将相邻的两个元素进行比较, 可能需要交换
		for (int j = 1; j < ps->_size - i; ++j)
		{
			if (ps->_array[j-1] > ps->_array[j])
			{
				Ischange = 1;
				Swap(&ps->_array[j-1], &ps->_array[j]);
			}
		}

		if (!Ischange)
			return;
	}
}

二分查找

int SeqListBInarySearch(PSeq ps,DataType data)
{
	assert(ps);
	size_t left = 0;
	size_t right = ps->_size - 1;
	while (left<=right)
	{
		int mid = left + (right - left) / 2;
		if (ps->_array[mid]==data)
		{
			return mid;
		}
		if (ps->_array[mid]>x)
		{
			right = mid - 1;
		}
		if (ps->_array[mid]<x)
		{
			left = mid + 1;
		}
	}
	return -1;
}

最后的测试程序

//测试程序
void TestSeqList()
{
	SeqList s;
	int pos = -1;
	SeqListInit(&s, 10);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 6);
	SeqListPushBack(&s, 7);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 9);
	SeqListPushBack(&s, 2);
	printf("size = %d\n", SeqListSize(&s));
	printf("capacity = %d\n", SeqListCapacity(&s));
	SeqListPrint(&s);

	SeqListRemoveAll(&s, 2);
	SeqListPrint(&s);

	SeqListPushBack(&s, 1);
	printf("size = %d\n", SeqListSize(&s));
	printf("capacity = %d\n", SeqListCapacity(&s));
	SeqListPrint(&s);

	SeqListPopBack(&s);
	SeqListPrint(&s);

	SeqListPushFront(&s, 0);
	SeqListPrint(&s);

	SeqListPopFront(&s);
	SeqListPrint(&s);

	SeqListInsert(&s, 1, 5);
	SeqListPrint(&s);

	pos = SeqListFind(&s, 5);
	if (pos != -1)
		printf("5 is in %d!!!\n", pos);
	else
		printf("5 is not in %d!!!\n", pos);

	SeqListErase(&s, 1);

	pos = SeqListFind(&s, 5);
	if (pos != -1)
		printf("5 is in %d!!!\n", pos);
	else
		printf("5 is not in %d!!!\n", pos);

	SeqListPrint(&s);
	printf("size = %d\n", SeqListSize(&s));
	printf("capacity = %d\n", SeqListCapacity(&s));

	SeqListDestroy(&s);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值