【数据结构】顺序表

顺序表是数据结构中最简单也是最基础的一种存放数据的方式,它的基本实现是我们需要定义一个结构体,比如说我们要存放全是int类型的数据,那么在结构体中我们就需要定义一个指向int类型数据的指针,为了动态开辟内存,和当前顺序表的容量和所存放的数据的个数。

这就是我们要实现的一个基本思想,其实和前面写的通讯录是差不多的,只不过我们在顺序表中要有更多的操作和存储各种不同类型的东西。

首先是要定义我们要存储的数据类型,我们可以用typedef类型重定义一下

typedef int SLDataType;//这里不要忘记要加上分号

之后就是定义我们的顺序表了

typedef struct SeqList {
	SLDataType* a;//这里创建一个指针为了后面的动态内存开辟
	int size;//存储有效数据个数
	int capacity;//容量大小
}SL;//这里也是类型重定义一下,让我们后面用起来更加方便

等我们创建完一个数据表的类型,就在主函数中创建一个顺序表

SL s1;//记住这里可千万不要创建错了,类型+名字

之后就是初始化了

void SLInit(SL* ps) {
	assert(ps);//断言传进来的不能是一个空指针,正常就是一个指向顺序表的指针
	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//先分配4个数据的空间
	if (ps->a == NULL) {
		perror("malloc failed");//如果出错会报错误信息
		exit(-1);//直接退出程序
	}
	ps->size = 0;
	ps->capacity = 4;
}

下面我们来写一下打印函数,负责打印顺序表中的信息

void SLPrint(SL* ps) {
	assert(ps);
	for (int i = 0; i < ps->size; i++) {//依靠循环逐个打印顺序表中的信息
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

动态内存分配不用后我们要free掉,所以我们在程序最后要销毁掉顺序表

void SLDestroy(SL* ps) {
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

接下来就是我们的插入和删除数据了,分为顺序表的头,尾和任意位置的插入删除

首先在插入之前我们要检测顺序表是否已满,如果满了,我们需要扩容

void SLCheckCapacity(SL* ps) {//如果容量不够要进行扩容
	assert(ps);
	if (ps->size == ps->capacity) {
		SLDataType* tmp = (SLDataType*)realloc(ps->a,sizeof(SLDataType) * ps->capacity * 2);
		if (tmp == NULL) {
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;//这里扩容后容量是之前的二倍
	}
}
void SLPushBack(SL* ps,SLDataType x);//尾插数据

void SLPopBack(SL* ps);//尾删数据

void SLPushFront(SL* ps, SLDataType x);//头插数据

void SLPopFront(SL* ps);//头删数据

void SLInsert(SL* ps, int pos, SLDataType x);//在pos位置插入元素

void SLErase(SL* ps, int pos);//删除pos位置的元素

这些代码在文章的最后都会有,需要注意的是什么呢,
如果在尾部插入和删除的话,很容易操作,最后size要进行自增或自减
如果是在头部和中间操作的话,就得整体移动后面的数据,
最后在前面不要忘记对参数的合法性和有效性进行判断

最后所有的函数实现呈上

#include"SeqList.h"


void SLInit(SL* ps) {
	assert(ps);
	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);
	if (ps->a == NULL) {
		perror("malloc failed");
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;
}

void SLDestroy(SL* ps) {
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}


void SLPrint(SL* ps) {
	assert(ps);
	for (int i = 0; i < ps->size; i++) {
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}


void SLCheckCapacity(SL* ps) {//如果容量不够要进行扩容
	assert(ps);
	if (ps->size == ps->capacity) {
		SLDataType* tmp = (SLDataType*)realloc(ps->a,sizeof(SLDataType) * ps->capacity * 2);
		if (tmp == NULL) {
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}


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


void SLPopBack(SL* ps) {
	assert(ps);
	assert(ps->size > 0);
	ps->size--;
}


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


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


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


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->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->size++;
}

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

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

typedef struct SeqList {
	SLDataType* a;
	int size;//存储有效数据个数
	int capacity;//容量大小
}SL;

void SLInit(SL* ps);//初始化顺序表

void SLDestroy(SL* ps);//销毁顺序表

void SLPrint(SL* ps);//打印顺序表

void SLPushBack(SL* ps,SLDataType x);//尾插数据

void SLPopBack(SL* ps);//尾删数据

void SLPushFront(SL* ps, SLDataType x);//头插数据

void SLPopFront(SL* ps);//头删数据

void SLInsert(SL* ps, int pos, SLDataType x);//在pos位置插入元素

void SLErase(SL* ps, int pos);//删除pos位置的元素

int SLFind(SL* ps, SLDataType x);//查找顺序表中的元素

void SLModify(SL* ps, int pos, SLDataType x);//改pos位置的数据为x

你可能感兴趣的:(数据结构,算法)