C语言实现顺序表(注释非常详细了)

定义顺序表和元素

//定义数据元素的数据项
typedef struct 
{
	int id;
	char* name;
}ElementType;

//定义顺序表
typedef struct
{
	ElementType datas[MAX_SIZE];     //顺序表中的元素的集合,每个元素是一个结构体,其中有两个数据项
	int length;					    //当前顺序表长度
}SeqList;

主函数逻辑调用

int main(void)
{
	ElementType element_array[] = { {1, "whoami"}, {2, "killer"}, {3, "avenger"}, {4, "thread"}, {5, "thundeing"}, {6, "hacker"} };
	ElementType element1 = { 4, "hhhhhh" };
	SeqList seqlist;   //定义一个顺序表,用来传入以进行初始化
	InitList(&seqlist, element_array, sizeof(element_array) / sizeof(element_array[0]));  //传入数据以初始化顺序表

	InsertElement(&seqlist, 3, element1);

	PrintfElement(&seqlist);


	printf("删除下标4处的元素\n");
	ElementType* element2 =  DeleteElement(&seqlist, 4);
	PrintfElement(&seqlist);
	printf("被删除的元素是: ");
	printf("%d  %s\n", element2->id, element2->name);
	free(element2);

	ClearList(&seqlist);
	PrintfElement(&seqlist);
	
	system("pause");
	return 0;
}

初始化顺序表

void InitList(SeqList* seqlist, ElementType* Array, int length)
{
	
	if (length > MAX_SIZE) 
	{
		printf("初始化长度大于数组总长度,初始化失败\n");
		return;
	}

	seqlist->length = 0;    //顺序表初始长度为0 和length不同,length是顺序表要变长的长度
	//每次循环都在下标为i处插入一个元素
	for (int i = 0; i < length; i++)
	{
		InsertElement(seqlist, i, Array[i]);   //向seqlist顺序表中的i下标位置插入Array数组中的第i个元素
	}
}

顺序表插入

void InsertElement(SeqList* seqlist, int index, ElementType element)
{
	//1.检查插入后顺序表长度是否超过数组最大长度
	//2.检查index是否合法,在[0, MAX_SIZE-1]之间
	//3.插入的index是否在length之内  length是初始化的顺序表的长度
	//4.在插入时,从length-1(这里的length-1指的是下标了)处到index处,所有元素往后挪一个位置(含原index处元素)  Eg: 12,34,56,98,99 我们要在index为2处插入100
																									  //则应变为: 12,34,100,56,98,99 (length-1等于4,是99,从99开始往后挪)
	//5.将要插入的值赋给index处
	//6.顺序表的总长度+1 !!!!!!!!!!!!!!!!!!!!
	if (seqlist->length + 1 >= MAX_SIZE) 
	{
		printf("数组已满,插入元素失败\n");
		return;
	}
	if (index<0 || index>MAX_SIZE - 1)
	{
		printf("插入下标不合法,插入元素失败\n");
		return;
	}
	if (index > seqlist->length)
	{
		printf("插入下标位置大于顺序表长度,插入元素失败\n");
		return;
	}
	for (int i = seqlist->length-1; i >= index; i--)
	{
		seqlist->datas[i + 1] = seqlist->datas[i];  //前一个元素赋给后一个,往后挪
		seqlist->datas[i + 1].id += 1;    //让[i + 1]下标的序号+1的原因:因为在这一句上面,datas[i]包含了id和name,覆盖了下一个的id,因此实际上是
										 // 原:1 2 3 4 5 6  覆盖后:1 2 3 4 4 5 6 注意下标,原的最大下标是5,而覆盖后最大下标是6,而i最小值是index为3,对应序号第一个4
										 // 而i初始值是5, 5+1=6,下标为6处刚好是最后一个id,然后id+1, 下次循环时下标为5,id为5, 5+1=6
										// 总的来说,是因为插入后,下标索引也改变了

	}
	seqlist->datas[index] = element;   //5.将要插入的值赋给index处
	seqlist->length += 1;			  //6.顺序表的总长度+1 !!!!!!!!!!!!!!!!!!!!
}

顺序表获取元素(返回值用来在删除中作为返回被删除元素)

/* 返回要对应下标的元素
*  index:要返回的元素的下标
*  return:返回指定下标的元素,如果不存在返回NULL
*/
ElementType* GetElement(SeqList* seqlist, int index)
{
	//1.判断下标是否合法
	if (index<0 || index>MAX_SIZE - 1)
	{
		printf("下标不合法,查找失败");
		return NULL;
	}
	ElementType* element;  //要查找的元素
	element = &seqlist->datas[index];

	return element;
}

删除元素

/*  
*   删除指定下标的元素,并返回该元素,如果删除失败返回NULL
*/
ElementType* DeleteElement(SeqList* seqlist, int index)
{
	//1. 检查要删除的元素下标index是否超过seqlist的当前长度
	//2. 检查index是否在合法范围内
	//3.当表长度为0时为空表,所以检查是否为空表
	//4.找到要删除的元素并保存,以便返回
	if (index > seqlist->length)
	{
		printf("欲删除元素下标超过当前顺序表长度,删除失败");
		return NULL;
	}
	if (index<0 || index>MAX_SIZE - 1)
	{
		printf("下标不合法,删除失败");
		return NULL;
	}
	if (seqlist->length == 0)
	{
		printf("当前顺序表为空表,删除失败");
		return NULL;
	}

	ElementType* deletelement = (ElementType* )malloc(sizeof(ElementType));  //直接申请一块空间,用来保存GetElement的返回值指针对应存储单元中的值(就是用来保存即将被删的index对应的元素,形成一个副本)
	*deletelement = *GetElement(seqlist, index);							//我们需要保存的是值(因此用*取),*deletelement就是malloc的空间,*GetElement就是   
																		    //获取到的需要保存的元素,返回值为地址,加个*取出值,赋值给malloc空间即可   (也可以直接seqlist->datas[index]赋值给deletelement,因为这时候index对应元素还没被删除,可以保存在malloc空间形成副本并返回)
	for (int i = index; i < seqlist->length; i++)
	{
		seqlist->datas[i] = seqlist->datas[i + 1]; 
		seqlist->datas[i].id -= 1;                   //序号-1,代替被删除元素的序号
	}
	
	seqlist->length -= 1;  //删除一次后减顺序表长度-1

	return deletelement;
}

清空顺序表

void ClearList(SeqList* seqlist)
{
	seqlist->length = 0;
}

打印顺序表

void PrintfElement(SeqList* seqlist)
{
	for (int i = 0; i < seqlist->length; i++)
	{
		printf("%d  %s\n\n", seqlist->datas[i].id, seqlist->datas[i].name);
	}
}
  • 24
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值