线性表
线性表是包含若干数据元素的一个线性序列
记为: L=(a0, … ai-1, ai, ai+1 … an-1)
L为表名,ai (0≤i≤n-1)为数据元素;n为表长,n>0 时,线性表L为非空表,否则为空表。
线性表L可用二元组形式描述:
L= (D,R)即线性表L包含数据元素集合D和关系集合R
D={ai | ai∈datatype ,i=0,1,2, ∙∙∙∙∙∙∙∙∙n-1 ,n≥0}
R={<ai , ai+1> | ai , ai+1∈D, 0≤i≤n-2}
关系符<ai, ai+1>在这里称为有序对,表示任意相邻的两个元素之间的一种先后次序关系。ai是ai+1的直接前驱, ai+1是ai的直接后继。
线性表的特征:
- 对非空表,a0是表头,无前驱;
- an-1是表尾,无后继;
- 其它的每个元素ai有且仅有一个直接前驱ai-1和一个直接后继ai+1。
顺序存储的优缺点
线性表的顺序存储结构有存储密度高及能够随机存取等优点
但存在以下不足:
(1)要求系统提供一片较大的连续存储空间。
(2)插入、删除等运算耗时,且存在元素在存储器中成片移动的现象;
运算实现的代码
sqlist.h文件
#define N 128
typedef int data_t;
typedef struct {
data_t data[N];
int last;
}sqlist, *sqlink;
sqlink list_create();//创建顺序表
int list_clear(sqlink L);//清除
int list_empty(sqlink L);//判空
int list_length(sqlink L);//表长
int list_locate(sqlink L,data_t value);//元素定位
int list_insert(sqlink L,data_t value,int pos);//插入
int list_delete(sqlink L,int pos);//删除
int list_merge(sqlink L1,sqlink L2);//合并L1和L2,L1 = L1 U L2
int list_purge(sqlink L);//除重
int list_show(sqlink L);//展示
sqlist.c文件
#include <stdio.h>
#include "sqlist.h"
#include <stdlib.h>
#include <string.h>
sqlink list_create()
{
sqlink L;
L = (sqlink)malloc(sizeof(sqlist));
if(L == NULL)
{
printf("list malloc failed\n");
return L;
}
memset(L,0,sizeof(sqlist));
L->last = -1;
return L;
}
int list_clear(sqlink L)
{
if(L == NULL)
return -1;
memset(L,0,sizeof(sqlist));
L->last = -1;
return 0;
}
int list_empty(sqlink L)
{
if(L->last == -1)
return -1;
else
return 0;
}
int list_length(sqlink L)
{
if(L == NULL)
return -1;
return (L->last+1);
}
int list_locate(sqlink L,data_t value)
{
int i;
for(i=0; i<=L->last; i++)
{
if(L->data[i]==value)
return i;
}
return -1;
}
int list_insert(sqlink L,data_t value,int pos)
{
int i;
if(L->last == N - 1)
{
printf("list is full\n");
return -1;
}
if(pos < 0 || pos > L->last+1)
{
printf("pos is invalid\n");
return -1;
}
for(i = L->last; i>=pos; i--)
{
L->data[i+1]=L->data[i];
}
L->data[pos] = value;
L->last++;
return 0;
}
int list_delete(sqlink L,int pos)
{
int i;
if(L->last == -1)
{
printf("list is empty\n");
return -1;
}
if(pos <0||pos>L->last)
{
printf("delete pos is invalid\n");
return -1;
}
for(i=pos+1; i<=L->last; i++)
{
L->data[i-1] = L->data[i];
}
L->last--;
return 0;
}
int list_merge(sqlink L1, sqlink L2)
{
int i=0;
int ret;
while(i<=L2->last)
{
ret = list_locate(L1,L2->data[i]);
if(ret==-1)
{
if(list_insert(L1,L2->data[i],L1->last+1)==-1)
return -1;
}
i++;
}
return 0;
}
int list_purge(sqlink L)
{
int i;
int j;
if(L->last==0)
return 0;
i=1;
while(i<=L->last)
{
j=i-1;
while(j>=0)
{
if(L->data[i]==L->data[j])
{
list_delete(L,i);
break;
}
else
{
j--;
}
}
if(j<0)
{
i++;
}
}
return 0;
}
int list_show(sqlink L)
{
int i;
if(L == NULL)
return -1;
if(L->last == -1)
printf("list is empty\n");
for(i=0; i<=L->last; i++)
{
printf("%d ",L->data[i]);
}
puts("");
return 0;
}
test.c文件
#include <stdio.h>
#include "sqlist.h"
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[])
{
sqlink L;
L = list_create();
if(L == NULL)
return -1;
list_insert(L,10,0);
list_insert(L,20,0);
list_insert(L,30,0);
list_insert(L,30,0);
list_insert(L,30,0);
list_show(L);//30 30 30 20 10
list_delete(L,3);//3是下标,即删除第4个相当于顺数的第二个
list_show(L);//30 30 30 10
return 0;
}
把这三个文件放一个文件夹,然后在Linux里执行gcc *.c -Wall然后执行./a.out
案例是运用list_delete函数实现删除功能,还有其它函数功能比如插入、合并、去重…等你去实现