定义顺序表和元素
//定义数据元素的数据项
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);
}
}