sequence table (data structure)

Table of contents

Reminder

concept

content

1. Definition of sequence table

2. Initialization of the sequence table

3. Destruction of the sequence table

4. Check the space

5. Tail insertion of sequence table

6. Printing of the sequence table

7. Tail deletion of sequence table

8. The head plug of the sequence table

9. Delete the header of the sequence table

10. Insert at the specified position of the sequence table

 11. Deletion of the specified position value in the sequence table

12. Search of sequence table

13. Modify the value of the pos position in the sequence table

The total code (if you want to see the result directly, you can see here)

under SeqList.h

under SeqList.c

under Test.c


Reminder

SeqList.h is used for the referenced header file, the definition of the sequence table, and the function declaration of the interface.

SeqList.c is used for the definition of interface functions.

Test.c is used for the test of the sequence table function.


concept

A linear table is the most basic, simplest, and most commonly used data structure . A linear list is a finite sequence of n data elements with the same properties. Common linear tables: sequential lists, linked lists, stacks, queues, strings...

A linear table is logically a linear structure, that is to say, a continuous straight line. However, the physical structure is not necessarily continuous. When the linear table is physically stored, it is usually stored in the form of an array and a chain structure .
The sequence table is a linear structure in which data elements are sequentially stored in a storage unit with continuous physical addresses , and is generally stored in an array . Add, delete, check and modify data on the array.
          

 The sequence table is divided into: static sequence table and dynamic sequence table

1. Static sequence table: use a fixed-length array to store elements. ( Too much space is wasted, and less space is not enough )

2. Dynamic sequence table: use dynamically opened array storage. ( Apply on demand )

The static sequence table is only suitable for scenarios where you know how much data needs to be stored. It is not applicable to the actual situation in real life, so we will only explain the dynamic sequence table next.


content

1. Definition of sequence table

under SeqList.h

#pragma once//使同一个文件不会被包含(include)多次,不必担心宏名冲突。

//先将可能使用到的头文件写上
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int SLDataType;//顺序表的类型名称,给变量定义一个易于记忆且意义明确的新名字,
//并且便于以后存储其它类型时方便改动.
//(比如我晚点想存double类型的数据,我就直接将 int 改为 double )

typedef struct SeqList
{
	SLDataType* a;//指向动态开辟的数组。
	size_t size;//有效数据个数
	size_t capacity;//空间容量
}SL;
//struct 关键字和 SeqList 一起构成了这个结构类型。
//typedef 为这个结构起了一个别名,叫 SL,即:typedef struct SeqList SL 。
//现在就可以像 int 和 double 那样直接使用 SL 定义变量。

2. Initialization of the sequence table

under SeqList.h

#define INIT_CAPACITY 4//初始化的容量

//顺序表初始化
//我们传地址而不是传值,因为形参是实参的拷贝,形参的改变不影响实参。
void SLInit(SL* ps);

under SeqList.c

#include"SeqList.h"//别忘了

void SLInit(SL* ps)
{
    assert(ps);//断言

    //用malloc申请了一块空间
	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*INIT_CAPACITY);
    //表示:malloc申请开辟 sizeof(int)乘以4 即16个字节大小的空间后,强制类型转换成(int*)

    if (ps->a == NULL)//如果开辟失败
	{
		perror("malloc fail");//输出错误信息
		return;
	}
	ps->size = 0;
	ps->capacity = INIT_CAPACITY;//初始化的时候先开辟一点空间
}

remind:

Those who are familiar with malloc function and sizeof operator can skip this part.

The parameters in the malloc function are required to be of type size_t, and the return type is void*.

If the allocation is successful, a pointer to the allocated memory is returned, otherwise a null pointer NULL is returned.

When using malloc to open up space, be sure to release the space (free) after use, otherwise it will cause a memory leak.

For the header file of malloc, the stdlib.h header file is recommended in the ANSI standard , but many C compilers require malloc.h.

 under Test.c

#include"SeqList.h"//别忘了

//用于接口函数功能的测试
void TestSeqList1()
{
	SL s;
	SLInit(&s);
}

int main()
{
	TestSeqList1();//调用测试函数
	return 0;
}

3. Destruction of the sequence table

under SeqList.h

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

under SeqList.c

// 顺序表销毁
void SLDestroy(SL* ps)
{
    assert(ps);//断言,最好加上,防止有些人直接将指针初始化为 NULL,而不用SLInit()函数
	free(ps->a);//释放a
	ps->a = NULL;//归还空间
	ps->capacity = ps->size = 0;//有效数据个数和空间容量都赋值为0
    //将0赋给size,再将size赋给capacity
}

under Test.c

//用于接口函数功能的测试
void TestSeqList1()
{
	SL s;
	SLInit(&s);
	SLDestroy(&s);
}

4. Check the space

under SeqList.h

//检查空间,如果满了,进行增容
void SLCheckCapacity(SL* ps);

under SeqList.c

The capacity expansion is generally 2 times at a time, and you can also expand 3 times or 4 times.

//检查空间
void SLCheckCapacity(SL* ps)
{
	assert(ps);//断言

	//判断是否扩容,若是,则扩
	if (ps->size == ps->capacity)//若最后一个数据的下一个位置的下标等于空间容量,则需扩容
	{
	   //realloc的注意事项可看下文。
	   //很多人容易把下面这一行代码写成
       //SLDataType*tmp=(SLDataType*)realloc(ps->a,ps->capacity*2);->这只扩到8个字节
	   SLDataType*temp=(SLDataType*)realloc(ps->a,sizeof(SLDataType)*ps->capacity*2);
	   //扩的空间是原来的两倍->扩到32个字节
	   //realloc(a地址,izeof(int)*4*2)后强制类型转化,
       //从void*转化成int*类型,赋值给int*类型的temp

	   if (temp == NULL)//如果申请失败
	   {
		   perror("realloc fail");//报错
		   return;
	   }
	   ps->a = temp;//a接收realloc返回的指针,realloc不一定原地扩容,可能原地、异地
	   //如果美甲上面那行代码程序没有报错,只是巧合,刚好原地扩容了。
	   ps->capacity *= 2;//如果扩容成功,size不变,capacity是原来2倍
	}
}

remind:

Those who are familiar with the realloc function can skip this part.

The realloc function returns a pointer of void* type, pointing to the starting address of the memory block newly opened in the heap area, ptr is the pointer of the previously opened memory block, size_t size refers to New size in bytes, the new number of bytes , note that it is not the number of bytes added, but the number of bytes of the newly opened memory space. If the application fails, it will return NULL, at this time, the original pointer is still valid. If the call is successful, regardless of whether the free space behind the current memory segment meets the requirements, the original pointer will be released and a new pointer will be returned.

5. Tail insertion of sequence table

under SeqList.h

// 顺序表尾插——在顺序表的最后插入一个数据
void SLPushBack(SL* ps, SLDataType x);//x为插入的数据

under SeqList.c

It can be seen from the figure: sz is the number of data, and it is also the subscript of the next position of the last data .

//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
    assert(ps);//断言
    SLCheckCapacity(ps);//扩容

    if (temp == NULL)//如果申请失败
	{
	    perror("realloc fail");//报错
		return;
	}

	//sz是数据个数,同时也是最后一个数据的下一个位置的下标
	ps->a[ps->size++] = x;
	//意思是:ps->a[ps->size] = x;
	//		 ps->size++;
}

under Test.c

//用于接口函数功能的测试
void TestSeqList1()
{
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPushBack(&s, 5);
	SLPushBack(&s, 6);
	SLDestroy(&s);
}

6. Printing of the sequence table

under SeqList.h

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

under SeqList.c

// 顺序表打印
void SLPrint(SL* ps)
{
    assert(ps);//断言
	for (size_t i = 0; i < ps->size; ++i)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

under Test.c

//用于接口函数功能的测试
void TestSeqList1()
{
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPushBack(&s, 5);
	SLPushBack(&s, 6);
	SLPrint(&s);
	SLDestroy(&s);
}

7. Tail deletion of sequence table

under SeqList.h

// 顺序表尾删——在顺序表的最后删除一个数据
void SLPopBack(SL* ps);

under SeqList.c

// 顺序表尾删
void SLPopBack(SL* ps)
{
    assert(ps);//断言
	//size为 0之后就不能再删除了!
	if (ps->size == 0)
	{
		return;
	}
	//或者
	//assert(ps->size>0);

	//加不加 ps->a[ps->size - 1] = 0;都无所谓
	ps->size--;
}

under Test.c

//用于接口函数功能的测试
void TestSeqList1()
{
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPushBack(&s, 5);
	SLPushBack(&s, 6);
	SLPrint(&s);

	SLPopBack(&s);
	SLPopBack(&s);
	SLPrint(&s);

	SLDestroy(&s);
}

remind:

If the size continues to decrease after it is 0, the size will take the value of max (int).

 

Notice:

Many people have a question here, that is, the sequence table can be expanded, so can it be reduced (released) after I delete the tail?

No, because the memory management of the operating system does not support it. The operating system supports the application and release of entire blocks of memory.

8. The head plug of the sequence table

Idea: move data (reflected in SeqList.c)

............ 

 

under SeqList.h

// 顺序表头插——在顺序表的开头插入一个数据
void SLPushFront(SL* ps, SLDataType x);//x为插入的数据

under SeqList.c

// 顺序表头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);//断言
	SLCheckCapacity(ps);//扩容

	int end = (int)ps->size - 1;//思路理解看上图
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[0] = x;
	ps->size++;
}

under Test.c

//用于接口函数功能的测试
void TestSeqList2()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);
}


int main()
{
	//TestSeqList1();
	TestSeqList2();
	return 0;
}

9. Delete the header of the sequence table

Idea: move data (reflected in SeqList.c)

 

 .........

under SeqList.h

// 顺序表头删——在顺序表的开头删除一个数据
void SLPopFront(SL* ps);

under SeqList.c

// 顺序表头删
void SLPopFront(SL* ps)
{
	assert(ps);//断言
	assert(ps->size > 0);//防止size为 0的时候,跳过循环,继续减减。
	int begin = 1;//思路理解看上图
	while (begin < (int)ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

under Test.c

void TestSeqList2()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);

	SLPopFront(&s);
	SLPrint(&s);
	SLPopFront(&s);
	SLPrint(&s);
	SLPopFront(&s);
	SLPrint(&s);
}

Note: Head insert/head delete N data time complexity is 0(N^2)

           The time complexity of tail insertion/deletion of N data is 0(N)

10. Insert at the specified position of the sequence table

Idea: move data (reflected in SeqList.c)

 

 

 

 

under SeqList.h

// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x);

 under SeqList.c

// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x)
{
	assert(ps);//断言
	assert(pos >= 0 && pos <= ps->size);//保证pos在0与size之间
	//取等时相当于头插/尾插
	SLCheckCapacity(ps);//扩容

	int end = ps->size - 1;
	while (end >= (int)pos)//这里特别注意强制类型转换
    //不改动其它,只将int end改成 size_t end会走死循环
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	
	//或者下面这种写法
	//size_t end = ps->size;
	//while (end >pos)
	//{
	//	ps->a[end] = ps->a[end-1];
	//	--end;
	//}

	ps->a[pos] = x;
	ps->size++;
}

After learning the function of inserting a value at a specified position, I found that this function can also be used for head insertion and tail insertion. Right now:

void SLPushFront(SL* ps, SLDataType x)
{
    SLInsert(ps,0,x);
}
void SLPushBack(SL* ps, SLDataType x)
{
    SLInsert(ps,ps->size,x);
}

under Test.c

//用于接口函数功能的测试
void TestSeqList3()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 0);
	SLPushFront(&s, 2);

	SLInsert(&s,0,5);
	SLPrint(&s);
}

int main()
{
	//TestSeqList1();
	//TestSeqList2();
	TestSeqList3();
	return 0;
}

 11. Deletion of the specified position value in the sequence table

Idea: move data (reflected in SeqList.c)

 

 

under SeqList.h

// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos);

 under SeqList.c

// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	//注意:pos不能等于size,这里和指定位置插入不一样,
    //并且间接防止了size为0的时候,跳过循环,继续减减。
	int begin = pos + 1;
	while (begin <(int)ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

under Test.c

void TestSeqList4()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPushFront(&s, 6);
	SLPushFront(&s, 7);
	SLPushFront(&s, 8);
	SLPushFront(&s, 9);
	SLPrint(&s);

	SLInsert(&s, 4, 666);
	SLPrint(&s);

	SLInsert(&s, 0, 666);
	SLPrint(&s);

	SLErase(&s, 4);
	SLPrint(&s);

	SLErase(&s, 4);
	SLPrint(&s);
}

int main()
{
	//TestSeqList1();
	//TestSeqList2();
	//TestSeqList3();
	TestSeqList4();
	return 0;
}

 After learning the function of deleting the value at the specified position, I found that this function can also be used for head deletion and tail deletion. Right now:

void SLPopFront(SL* ps)
{
    SLErase(ps,0);
}
void SLPopBack(SL* ps)
{
    SLErase(ps,ps->size-1);
}

12. Search of sequence table

under SeqList.h

// 顺序表查找
int SLFind(SL* ps, SLDataType x);//x为查找的数据

 under SeqList.c

// 顺序表查找
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < (int)ps->size; ++i)
	{
		if (ps->a[i] == x)//如果找到了
		{
			return i;//则返回要找的值的下标
		}
	}
	return -1;//否则返回-1
}

under Test.c

void TestSeqList5()
{
	SL s;
	SLInit(&s);
	int result = 0;

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);

	result=SLFind(&s, 3);
	printf("%d\n", result);

}


int main()
{
	//TestSeqList1();
	//TestSeqList2();
	//TestSeqList3();
	//TestSeqList4();
	TestSeqList5();
	return 0;
}

13. Modify the value of the pos position in the sequence table

under SeqList.h

//顺序表修改pos位置的值
void SLModify(SL* ps, size_t pos, SLDataType x);//x为修改后的值

 under SeqList.c

//顺序表修改pos位置的值
void SLModify(SL* ps, size_t pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//既防止了size等于0,又规范了pos的位置
	ps->a[pos] = x;
}

under Test.c

void TestSeqList6()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);

	SLModify(&s, 2, 1);
	SLPrint(&s);
}


int main()
{
	//TestSeqList1();
	//TestSeqList2();
	//TestSeqList3();
	//TestSeqList4();
	//TestSeqList5();
	TestSeqList6();
	return 0;
}

The total code (if you want to see the result directly, you can see here)

under SeqList.h

#pragma once//使同一个文件不会被包含(include)多次,不必担心宏名冲突。

//使用到的头文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int SLDataType;//顺序表的类型名称,给变量定义一个易于记忆且意义明确的新名字,
//并且便于以后存储其它类型时方便改动。
//(比如我晚点想存double类型的数据,我就直接将int改为double)

#define INIT_CAPACITY 4//初始化的容量

typedef struct SeqList
{
	SLDataType* a;//指向动态开辟的数组
	size_t size;//有效数据个数
	size_t capacity;//空间容量
}SL;
//struct 关键字和 SeqList 一起构成了这个结构类型。
//typedef 为这个结构起了一个别名,叫 SL,即:typedef struct SeqList SL 。
//现在就可以像 int 和 double 那样直接使用 SL 定义变量。

//基本增删查改接口

//顺序表初始化
//我们传地址而不是传值,因为形参是实参的拷贝,形参的改变不影响实参。
void SLInit(SL* ps);

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

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

// 顺序表尾插——在顺序表的最后插入一个数据
void SLPushBack(SL* ps, SLDataType x);//x为插入的数据

// 顺序表尾删——在顺序表的最后删除一个数据
void SLPopBack(SL* ps);

// 顺序表头插——在顺序表的开头插入一个数据
void SLPushFront(SL* ps, SLDataType x);//x为插入的数据

// 顺序表头删——在顺序表的开头删除一个数据
void SLPopFront(SL* ps);

//检查空间,如果满了,进行增容
void SLCheckCapacity(SL* ps);

// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x);//x为插入的数据

// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos);

// 顺序表查找
int SLFind(SL* ps, SLDataType x);//x为查找的数据

//顺序表修改pos位置的值
void SLModify(SL* ps, size_t pos, SLDataType x);//x为修改后的值

under SeqList.c

#include"SeqList.h"//别忘了

//顺序表初始化
void SLInit(SL* ps)
{
	assert(ps);//断言

	//用malloc申请了一块空间
	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*INIT_CAPACITY);
    //表示:malloc申请开辟 sizeof(int)乘以4 
    //即16个字节大小的空间后,强制类型转换成(int*)

	if (ps->a == NULL)//如果开辟失败
	{
		perror("malloc fail");//输出错误信息
		return;
	}
	ps->size = 0;
	ps->capacity = INIT_CAPACITY;//初始化的时候先开辟一点空间
}

// 顺序表销毁
void SLDestroy(SL* ps)
{
	assert(ps);//断言,最好加上,防止有些人直接将指针初始化为NULL,而不用SLInit()函数
	free(ps->a);//释放a
	ps->a = NULL;//归还空间
	ps->capacity = ps->size = 0;//有效数据个数和空间容量都赋值为0
}

//检查空间
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	//判断是否扩容,若是,则扩
	if (ps->size == ps->capacity)//若最后一个数据的下一个位置的下标等于空间容量,则需扩容
	{
		//realloc的注意事项可看下文。
		//很多人容易把下面这一行代码写成
        //SLDataType*tmp=(SLDataType*)realloc(ps->a,ps->capacity*2);->这只扩到8个字节
		SLDataType*temp=(SLDataType*)realloc(ps->a,sizeof(SLDataType)*ps->capacity*2);
		//扩的空间是原来的两倍->扩到32个字节
		//realloc(a地址sizeof(int)*4*2)后,
        //强制类型转化从void*转化成int*类型赋值给int*类型的temp

		if (temp == NULL)//如果申请失败
		{
			perror("realloc fail");//报错
			return;
		}
		ps->a = temp;//a接收realloc返回的指针,realloc不一定原地扩容,可能原地、异地
		如果美甲上面那行代码程序没有报错,只是巧合,刚好原地扩容了。
		ps->capacity *= 2;//如果扩容成功,size不变,capacity是原来2倍
	}
}

//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);//断言
	SLCheckCapacity(ps);//扩容

	//sz是数据个数,同时也是最后一个数据的下一个位置的下标
	ps->a[ps->size++] = x;
	//意思是:ps->a[ps->size] = x;
	//		 ps->size++;
}

// 顺序表打印
void SLPrint(SL* ps)
{
	assert(ps);//断言
	for (size_t i = 0; i < ps->size; ++i)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

// 顺序表尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	//size为0之后就不能再删除了!
	if (ps->size == 0)
	{
		return;
	}
	//或者
	//assert(ps->size>0);

	//加不加ps->a[ps->size - 1] = 0;都无所谓
	ps->size--;
}

// 顺序表头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);//断言
	SLCheckCapacity(ps);//扩容

	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[0] = x;
	ps->size++;
}


// 顺序表头删
void SLPopFront(SL* ps)
{
	assert(ps);//断言
	assert(ps->size > 0);//防止size为0的时候,跳过循环,继续减减。
	int begin = 1;
	while (begin < (int)ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}


// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x)
{
	assert(ps);//断言
	assert(pos >= 0 && pos <= ps->size);//保证pos在0与size之间
	//取等时相当于头插/尾插
	SLCheckCapacity(ps);//扩容

	int end = ps->size - 1;
	while (end >= (int)pos)//这里特别注意强制类型转换,不然容易死循环
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	
	//或者下面这种写法
	//size_t end = ps->size;
	//while (end >pos)
	//{
	//	ps->a[end] = ps->a[end-1];
	//	--end;
	//}

	ps->a[pos] = x;
	ps->size++;
}


// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos)
{
	assert(ps);//断言
	assert(pos >= 0 && pos < ps->size);
	//注意:
    //pos不能等于size,这里和指定位置插入不一样并且间接防止了size为0的时候,跳过循环,继续减减
	int begin = pos + 1;
	while (begin <(int)ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

// 顺序表查找
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < (int)ps->size; ++i)
	{
		if (ps->a[i] == x)//如果找到了
		{
			return i;//则返回要找的值的下标
		}
	}
	return -1;//否则返回-1
}

//顺序表修改pos位置的值
void SLModify(SL* ps, size_t pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//既防止了size等于0,又规范了pos的位置
	ps->a[pos] = x;
}

under Test.c

#include"SeqList.h"//别忘了

//用于接口函数功能的测试
void TestSeqList1()
{
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPushBack(&s, 5);
	SLPushBack(&s, 6);
	SLPrint(&s);

	SLPopBack(&s);
	SLPopBack(&s);
	SLPrint(&s);


	SLDestroy(&s);
}

void TestSeqList2()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);

	SLPopFront(&s);
	SLPrint(&s);
	SLPopFront(&s);
	SLPrint(&s);
	SLPopFront(&s);

	SLPrint(&s);
}

void TestSeqList3()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 0);
	SLPushFront(&s, 2);

	SLInsert(&s,0,5);
	SLPrint(&s);
}

void TestSeqList4()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPushFront(&s, 6);
	SLPushFront(&s, 7);
	SLPushFront(&s, 8);
	SLPushFront(&s, 9);
	SLPrint(&s);

	SLInsert(&s, 4, 666);
	SLPrint(&s);

	SLInsert(&s, 0, 666);
	SLPrint(&s);

	SLErase(&s, 4);
	SLPrint(&s);

	SLErase(&s, 4);
	SLPrint(&s);
}

void TestSeqList5()
{
	SL s;
	SLInit(&s);
	int result = 0;

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);

	result=SLFind(&s, 3);
	printf("%d\n", result);

}

void TestSeqList6()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLPushFront(&s, 5);
	SLPrint(&s);

	SLModify(&s, 2, 1);
	SLPrint(&s);
}


int main()
{
	//TestSeqList1();
	//TestSeqList2();
	//TestSeqList3();
	//TestSeqList4();
	//TestSeqList5();
	TestSeqList6();
	return 0;
}

Corrections are welcome❀

Guess you like

Origin blog.csdn.net/outdated_socks/article/details/129969820