# Sequential storage structure of sequential table

Keywords: data structure

## Sequential storage definition

Speaking of so many linear tables, let's take a look at the first of the two physical structures of linear tables - sequential storage structure.
The sequential storage structure of linear table refers to the sequential storage of data elements of linear table with a section of storage units with continuous addresses. The sequential storage diagram of linear table (a1,a2,..., an) is as follows:

## Sequential storage mode

The sequential storage structure of a linear table, to put it bluntly, is to find a block of space in the memory, occupy a certain memory space in the form of space occupation, and then store the data elements of the same data type in this space in turn. Since the types of each data element of a linear table are the same, you can use C language (the same for other languages) That is, the first data element is stored in the position where the index of the array is 0, and then the adjacent elements of the linear table are stored in the adjacent positions in the array.

In the linear table, we estimate the maximum storage capacity of the linear table and create an array. The length of the array is the maximum storage capacity. However, in actual use, we do not use the maximum storage capacity every time. We hope to use the space more efficiently. Therefore, we use malloc to apply for space and realloc to adjust the space size A little. You can see it Space allocation and release To understand the function in detail.

Look at the structure code of the sequential storage of the linear table.

```#define INITSIZE 20 / / initial size
#define EXPANDTIMES 2 / / expansion times of each time
typedef int ELemType; //Use int to simulate data item type
typedef struct
{
ElemType* data; //Initial location where data is stored
int capacity; //Capacity (total: unused + used)
}Sqlist;
```

I won't talk more about arrays and pointers here. If you want to know, you can see my Arrays and pointers.

### Init_List(*L)

```bool Init_List(Sqlist *L)
{
assert(L != NULL);//Check the input. The use of null pointers may lead to the collapse of the program. Search for the specific reasons and do not explain them later
L->data = (int*)malloc(sizeof(ELemType) * INITSIZE);//Request a heap space to store elements
//Assert (L - > data! = null); / / because malloc may fail, judge
if (L->data == NULL)
{
return false;
}
else
{
L->capacity = INITSIZE;//The initial capacity is set by macro definition
L->size = 0;//Of course, the initial size is 0
return true;
}
}
```

In order to have dynamic space size, we use heap space as storage space here. Don't remember free

### Change_List(*L, flag)

```bool Change_List(Sqlist* L,int flag)//Change capacity
{
assert(L != NULL);
ELemType* temp = L->data;
int newsize = flag == -1 ? L->capacity / EXPANDTIMES : L->capacity * EXPANDTIMES;//Simple judgment,
temp = (ELemType*)realloc(temp,newsize * sizeof(ELemType));//Capacity expansion may also fail to prevent old data loss
if (temp == NULL)
{
return false;
}
else
{
L->data = temp;//Give the requested space to data
L->capacity = newsize;//Change capacity
return true;
}
}
```

### Is_Empty(*L)

```bool Is_Empty(Sqlist* L)
{
assert(L != NULL);
return L->size == 0;//Just check that the size used is not 0, and it's ok
}
```

### Clear_List(*L)

```bool Clear_List(Sqlist* L)
{
assert(L != NULL);
free(L->data);//Because the space comes from malloc, free it if you don't need it
Init_List(L);//The simplest way is to re initialize it, which eliminates the data and reduces the capacity
//L->size = 0; / / the most simple way is that the data is valid, we has the final say, the capacity is unchanged.
return true;
}
```

### GetElem_List(*L,i)

```ELemType GetElem_List(Sqlist* L, int i)
{
assert(L != NULL && i < L->size && i >= 0);//Ensure that the changed subscript must be a valid subscript and will not be explained later
return L->data[i];
}
```

### LocateElem_List(*L,e)

```int LocateElem_List(Sqlist* L, ELemType e)
{
assert(L != NULL);
int pos = -1;
for (int i = 0; i < L->size; i++)//Traversal is required
{
if (e == L->data[i])
{
pos = i;
break;
}
}
return pos;
}
```

### Insert_List(*L,i,e)

```bool Insert_List(Sqlist* L,int i,ELemType e)
{
assert(L != NULL && i >= 0 && i <= L->size);//In order to meet the definition of linear table, the subscript shall be tested
if (L->capacity == L->size)//Capacity expansion is required due to insufficient capacity
{
if (!Change_List(L,1)) //Data can only be released after the expansion is successful
{
return false;
}
}
int pos = L->size;
while (L->size != i)//Move one bit back
{
L->data[pos] = L->data[pos - 1];
pos--;
}
L->data[pos] = e;
L->size++;
return true;
}
```

For tail insertion, I = L - > size; for head insertion, i=0;

### Delect_List(*L, i)

Reverse operation with insertion

```bool Delect_List(Sqlist* L, int i)//
{
assert(L != NULL && i < L->size && i >= 0);
while (i != L->size-1)//Move one bit forward
{
L->data[i] = L->data[i+1];
i++;
}
L->size--;
if (L->capacity > INITSIZE && L->size < L->capacity / EXPANDTIMES)
Change_List(L, -1);
return true;
}
```

### Length_List(*L)

```int Length_List(Sqlist* L)
{
assert(L != NULL);
return L->size;//We have special data items to record the length. Just return it directly
}
```

### Destory_List(*L)

Because clear only clears the data (some of the storage space cannot be cleared), we need to free it

```bool Destroy_List(Sqlist* L)
{
L->capacity = 0;
L->size = 0;
free(L->data);//Destroy can't use it at all, because 0 times any number is still 0
L->data = NULL;
return true;
}
```