顺序表的实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、前期准备

typedef int SLData;

typedef struct SeqList
{
	SLData* a;
	SLData size;
	SLData capacity;
}SL;
//初始化
void SLInit(SL* ps);
//打印
void SLPrint(SL* ps);

//检查是否有空间
void SLCheckCapacity(SL* ps);
//销毁
void SLDestory(SL* ps);

1.链表初始化

void SLInit(SL* ps)
{
	ps->a = NULL;//将指针置为空
	ps->capacity = ps->size = 0;//链表的序号和容量设为0
}

2.链表的打印

void SLPrint(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);//设一个for循环来打印
	}
	printf("\n");
}

3.检查链表的空间

void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)//如果序号和容量相等那说明空间已满,需要扩充空间
	{
		//设一个变量并判断容量是否为0,若为0给4个空间,不为0则扩大二倍
		int newnode = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//开辟一个动态空间,可保证容量随时扩充(按字节算)
		SLData* tmp = (SLData*)realloc(ps->a, sizeof(SLData) * newdata);
		if (tmp == NULL)
		{
			printf("relloc错误");
			exit(-1);
		}
		ps->capacity = newdata;//将变量和指针赋给ps对应的值
		ps->a = tmp;
	}
}

4.销毁链表

void SLDestory(SL* ps)
{
	assert(ps);
	if (ps->a)
	{
		free(ps->a);
		ps->a = NULL;//将指针置为空
		ps->capacity = ps->size = 0;//将序号和容量置为0
	}
}

二、头插和尾插

1.头插

void SLPushFront(SL* ps, SLData x)
{
	SLCheckCapacity(ps);//判断空间是否为满
	assert(ps);//防止为空指针
	int end = ps->size -1;//设一个end方便将数移动位置
	while (end >= 0)//用while循环以end为下标将数进行移位
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;//将头赋值
	ps->size++;//并将size+1
	//SLInsert(ps, 0, x);//可以使用下面的函数插入进行函数复用
}

2.尾插

void SLPushBack(SL* ps, SLData x)
{
	SLCheckCapacity(ps);//判断是否为满
	assert(ps);
	ps->a[ps->size] = x;//直接插入
	ps->size++;
	//SLInsert(ps,ps->size,x);//可以使用下面的函数插入进行函数复用
}

三、头删和尾删

1.头删

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);//断言 ps->size>0防止越界
	int begin = 1;//设begin为1,方便进行位置的移动
	while (begin<ps->size)//使用while循环将位置进行移动
	{
		ps->a[begin - 1] = ps->a[begin];//注意防止begin越界
		++begin;
	}
	ps->size--;
	//SLErase(ps, 0);

}

2.尾删

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	ps->size--;//直接删除
	//SLErase(ps,ps->size);
}

四、查找和修改

1.查找

int SLFind(SL* ps, SLData x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;//找到则传出序号
		}
	}
	return -1;//找不到则传出-1
}

2.修改

void SLModify(SL* ps, int pos, SLData x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);

	ps->a[pos] = x;//更改一般可以和查找搭配使用
}

5.插入和删除

1.插入

void SLInsert(SL* ps, int pos, SLData x)
{
	SLCheckCapacity(ps);//判断空间是否为满
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);//pos必须在0到size之间
	int end = ps->size - 1;//设一个end来作为下标移动数字
	while (end >= pos)
	{
		ps->a[end+1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;
}

2.删除

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

六、顺序表的实现

#define  _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void menu()
{
	printf("****************************\n");
	printf("1.头插  2.尾插\n");
	printf("3.头删  4.尾删\n");
	printf("5.查找  6.更改\n");
	printf("7.插入  8.删除\n");
	printf("9.销毁  0.退出\n");
	printf("****************************\n");
}
void test()
{
	menu();
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 0);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPrint(&sl);
	int option = -1;
	do
	{
		printf("请输入要选择的操作:>");
		while(scanf("%d", &option) == EOF)
		{
			printf("输入错误,请重新输入");
		}
		getchar();
		int x = 0;
		int y = 0;
		int pos = 0;
		switch (option)
		{
		case 1:
			printf("请输入头插的数字:>");
			scanf("%d", &x);
			SLPushFront(&sl, x);
			SLPrint(&sl);
			break;
		case 2:
			printf("请输入尾插的数字:>");
			scanf("%d", &x);
			SLPushBack(&sl, x);
			SLPrint(&sl);
			break;
		case 3:
			SLPopFront(&sl);
			SLPrint(&sl);
			break;
		case 4:
			SLPopBack(&sl);
			SLPrint(&sl);
			break;
		case 5:
			printf("请输入查找的数字:>");
			scanf("%d", &x);
			y = SLFind(&sl, x);
			if (y == -1)
			{
				printf("没找到\n");
			}
			else
			{
				printf("找到了\n");
			}
			break;
		case 6:
			printf("请输入要更改之前的和更改之后的数字:>");
			scanf("%d %d", &x, &y);
			x = SLFind(&sl, x);
			SLModify(&sl, x, y);
			SLPrint(&sl);
			break;
		case 7:
			printf("请输入要插入数的位置和要插入的数:>");
			scanf("%d %d", &pos, &x);
			SLInsert(&sl, pos, x);
			SLPrint(&sl);
			break;
		case 8:
			printf("请输入要删除的数>");
			scanf("%d", &x);
			pos = SLFind(&sl, x);
			SLErase(&sl, pos);
			SLPrint(&sl);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		};
	} while (option != 0);
}
int main()
{
	
	test();
	return 0;
}

在这里插入图片描述

总结

以上为顺序表实现的全部内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值