C语言数据结构顺序表的实现

前言

线性表的顺序存储结构,即顺序表,是指利用一块连续的地址空间依次存放线性表中的元素。这种数据结构被称作顺序映像,简称顺序表。其显著特征在于逻辑上相邻的元素,在物理存储上也是连续的。基于这个特性,顺序表允许通过起始地址加上偏移量的方式,即索引,实现对任意元素的随机访问,这使得顺序表成为一种随机访问存储结构。

顺序表的类型

typedef struct Seqlist
{
    int arr[];
    int size;//数据个数
    int capacity;//空间容量  
}sl;

1.这就是顺序表的第一种类型:静态顺序表。它是使用定长数组的顺序表,对于定长数组来说,数组给大了浪费内存,数组给小了空间不够用,所以一般来说不使用静态顺序表。

typedef struct seqlist
{
	int* a;
	int size;//数据个数
	int capacity;//容量
}sl;

2.顺序表的第二种类型:动态顺序表。它是使用动态增容的顺序表,它的内存会随着数据的增加而增加,所以不会像静态顺序表那样出现内存问题。

顺序表的主要操作

那么我们对顺序表的实现需完成以下操作 ,才能完成顺序表的实现:

1.顺序表的初始化。

2.顺序表的销毁。

3.顺序表的数据插入。

4.顺序表的查找。

5.顺序表的删除。

顺序表的初始化:

void initialize(sl* pa)//初始化
{
	pa->a = NULL;
	pa->capacity = pa->size = 0;
}

 顺序表的初始化就是构造一个空的顺序表,方便之后使用。

内存判断

 这里我们写的是动态顺序表那么我们就要对顺序表进行分配空间,如下:

void MJ(sq* pa)//内存判断
{
	if (pa->capacity == pa->size)//如果数据个数=内存容量,证明空间不够
	{
		int variable = pa->capacity == 0 ? 4 : 2 * pa->capacity;
		int* tmp = (int*)realloc(pa->a, variable * sizeof(lala));
		if (tmp == NULL)
		{
			printf("错了");
			exit(1);
		}
		pa->a = tmp;
		pa->capacity = variable;
	}
}

 这里我们运用三元操作符来判断内存容量是否为0,因为顺序表刚初始化完内存容量为0,随后创建一个临时变量并给予其内存空间(此内存空间用realloc创建,使其位于顺序表指针之后),创建临时变量是为了避免realloc操作失败返回NULL,如果创建成功,使pa->tmp更新顺序表结构体中的数组指针,让它指向新的内存地址。

顺序表的插入及删除

尾插法和尾删法,头插法和头删法

void SLPushBack(sl* pa, int x)//尾插法
{
	assert(pa);
	MJ(pa);
	pa->a[pa->size++] = x;

}
void SLPopBack(sl* pa)//尾插法删除
{
	assert(pa);
	assert(pa->size);
	--pa->size;
}
void SLPushFront(sl* pa, int x)//头插法
{
	assert(pa);
	MJ(pa);           
	int i;
	for (i = pa->size; i > 0; i--)
	{
		pa->a[i] = pa->a[i - 1];
	}
	pa->a[0] = x;
	pa->size++;

}
void SLPopFront(sl* pa)//头插法删除
{
	assert(pa);
	assert(pa->size);
	for (int i = 0; i < pa->size - 1; i++)
	{
		pa->a[i] = pa->a[i + 1]; 
	}
	pa->size--;
}

尾插法和尾删法都是从尾部进行插入和删除,头插法和头删法相反,在进行尾插法和头插法是都要进行断言指针是否为空,且要进行内存判断,避免内存不够用的情况。在进行尾删法和头删法是需断言指针和数据个数,避免对错误内容进行操作。

顺序表的查找

int find(sq* pa, int x)//查找
{
	assert(pa);
	for (int i = 0; i < pa->size; i++)
	{
		if (pa->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

x为查找的内容,如果查找成功,则会返回第几个a找到的x,如果找不到返回-1。

顺序表在指定位置的查找和删除

void yyy(sl* pa, int pos, int x)//在指定位置插入数据
{
	assert(pa);
	assert(pos >= 0 && pos <= pa->size);
	MJ(pa);
	for (int i = pa->size; i >= pos; i--)
	{
		pa->a[i] = pa->a[i - 1];
	}
	pa->size++;
	pa->a[pos] = x;
}
void aaa(sl* pa, int pos)//删除指定位置数据
{
	assert(pa);
	assert(pos >= 0 && pos < pa->size);
	MJ(pa);
	for (int i = pos; i < pa->size-1; i++)
	{
		pa->a[i] = pa->a[i + 1];
	}
	pa->size--;
}

顺序表在指定位置的插入和删除必须判断查找或删除(pos)位置是否合法,随后在进行查找和删除。

顺序表的销毁

void destory(sl* pa)//顺序表的销毁
{
	if (pa->a)
	{
		free(pa->a);
	}
	pa->a = NULL;
	pa->capacity = pa->size = 0;
}

在操作完成后需要销毁顺序表,将顺序表的内存还给系统。

完整代码如下                    

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int lala;

typedef struct seqlist
{
	lala* a;
	int size;//数据个数
	int capacity;//容量
}sq;
void initialize(sq* pa)//初始化
{
	pa->a = NULL;
	pa->capacity = pa->size = 0;
}
void destory(sq* pa)//顺序表的销毁
{
	if (pa->a)
	{
		free(pa->a);
	}
	pa->a = NULL;
	pa->capacity = pa->size = 0;
}
void MJ(sq* pa)//内存判断
{
	if (pa->capacity == pa->size)
	{
		int variable = pa->capacity == 0 ? 4 : 2 * pa->capacity;
		lala* tmp = (lala*)realloc(pa->a, variable * sizeof(lala));
		if (tmp == NULL)
		{
			printf("错了");
			exit(1);
		}
		pa->a = tmp;
		pa->capacity = variable;
	}
}
void SLPushBack(sq* pa, lala x)//尾插法
{
	assert(pa);
	MJ(pa);
	pa->a[pa->size++] = x;

}
void SLPushFront(sq* pa, lala x)//头插法
{
	assert(pa);
	MJ(pa);           
	int i;
	for (i = pa->size; i > 0; i--)
	{
		pa->a[i] = pa->a[i - 1];
	}
	pa->a[0] = x;
	pa->size++;

}

void SLPrint(sq s)//打印内容
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ", s.a[i]);
	}
	printf("\n");
}

void SLPopBack(sq* pa)//尾插法删除
{
	assert(pa);
	assert(pa->size);
	--pa->size;
}
void SLPopFront(sq* pa)//头插法删除
{
	assert(pa);
	assert(pa->size);
	for (int i = 0; i < pa->size - 1; i++)
	{
		pa->a[i] = pa->a[i + 1]; //arr[size-2] = arr[size-1]
	}
	pa->size--;
}
void yyy(sq* pa, int pos, lala x)//在指定位置插入数据
{
	assert(pa);
	assert(pos >= 0 && pos <= pa->size);
	MJ(pa);
	for (int i = pa->size; i >= pos; i--)
	{
		pa->a[i] = pa->a[i - 1];
	}
	pa->size++;
	pa->a[pos] = x;
}
void aaa(sq* pa, int pos)//删除指定位置数据
{
	assert(pa);
	assert(pos >= 0 && pos < pa->size);
	MJ(pa);
	for (int i = pos; i < pa->size-1; i++)
	{
		pa->a[i] = pa->a[i + 1];
	}
	pa->size--;
}
int find(sq* pa, lala x)//查找
{
	assert(pa);
	for (int i = 0; i < pa->size; i++)
	{
		if (pa->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

请注意,以上代码仅供学习和参考之用。对顺序表相关操作的理解和实现细节,有助于深入掌握数据结构的基本概念。如有任何疑问或建议,欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值