目录
用到的宏定义
#define ELEMTYPE int //数据类型
#define MAXSIZE 10 //定义最大长度
#define INITSIZE 10 //默认最大长度
#define ERROR -1
#define OK 1
静态线性表
结构体
typedef struct Sqlist
{
/* data */
ELEMTYPE data[MAXSIZE];
ELEMTYPE length; //长度
} SqList;
结构体调用方式:
1,通过结构体变量定义
Sqlist L;
L为Sqlist类型的结构体变量,利用L.data[i-1]可以访问序号为i的表元素,L.length为顺序表长度
2,通过指针变量定义
Sqlist *L;
L为Sqlist类型的指针变量,利用L->data[i-1]可以访问序号为i的表元素,而L->length为顺序表的长度。
静态初始化一个顺序表
void InitSqList(SqList * L, ELEMTYPE len)
{
L->length = len;
}
查找:
线性表具有两种基本查找运算:
(1)按照序号查找GetData(L, i):要求查找线性表中第i个元素,其结果是直接返回L.elem[i-1],或者直接返回L->data[i-1].
(2)按照内容查找Locate(L, e):要求查找数据元素e在线性表L中的位置。如果在表L中找到与e相等的元素则返回其在表中的序号;如果没有,则返回一个空序号,如-1.
按位查找(给出位号,查找这一尾号的元素)
ELEMTYPE Getdata(SqList * L, ELEMTYPE i)
{
return L->data[i - 1];
}
按值查找(已知元素,查找位号)
(方法1):
int Locatdata1(SqList * L, ELEMTYPE value)
{
for (int i = 0; i < L->length; i++)
{
if (value == L->data[i])
{
return (i + 1); //返回位序
}
return ERROR ;
}
}
(方法2)
int Locatdata2(SqList * L, ELEMTYPE value)
{
int i = 0;
while((i < L->length)&&(value != L->data[i]))
{
i++;
}
if((i < L->length)) return(i+1);
else return ERROR ;
}
算法时间复杂度的分析:算法中的基本操作是“移动元素”,在最坏的情况下(e为最后一个元素)为 L.last。此算法的时间复杂度为:O (n)
插入
在线性表 L= (a1,…a i-1,ai, ai+1,…,an) 中的第i(1≦i≦n)个元素位置上(元素ai之前)插入一个新结点e,使其成为线性表:L=(a1,…a i-1,e,ai,ai+1,…,an)
思路:
(1) 将线性表L中的第i个至第n个结点后移一个位置。
(2) 将结点e插入到结点ai-1之后。
(3) 线性表长度增加1。事先应判断:
(1)插入位置i 是否合法,表是否已满。
应当有1≤i≤n+1 或 i=[1,n+1],n为表中元素个数
(2)判断线性表空间是否足够。
int InsList(SqList *L, int i, ELEMTYPE e)
{
/*在顺序表L的第i个元素前插入e,表长n=L->length+1, 1<=i<=L->length+2*/
int k;
if(i<1 || i>L->length+2) /*用于挪动i及其后面的元素*/
{
printf("插入i位置不合法"); //i值不合法
return ERROR;
}
if(L->length>MAXSIZE)
{
printf("表已满无法插入"); //当前存储空间已满
return ERROR;
}
for(k=L->length;k>=i-1;k--) //第i个元素开始依次后移
{
L->data[k+1] = L->data[k];
}
L->data[i-1] = e;
L->length++; //表长加一
return OK;
}
删除
算法思想:删除第i(1≤i≤n)个元素时,将第(i+1)至第n(共n-i)个元素逐一向前移动一个位置。
在线性表 L=(a1,…a i-1,ai, ai+1,…,an) 中删除结点ai(1≦i≦n),使其成为线性表:
L= (a1,…ai-1,ai+1,…,an)
实现步骤:
(1) 将线性表L中的第i+1个至第n个结点依此向前移动一个位置。
(2) 线性表长度减1。
int ListDelete(SqList *L,int i,ELEMTYPE *e)
{ /*删除线性表L第i个元素并用指针参数e返回其值,1<=i<=L.length+1*/
int k;
if (i<1||i>L->length+1) //i值不合法
{
printf("删除位置不合法");
return ERROR;
}
*e=L->data[i-1]; //将被删除元素的值赋给指针e所指变量
for(k=i;k<=L->length;k++) //被删除元素之后的元素左移
L->data[k-1]= L->data[k];
L->length--; //表长减1
return (OK);
}//ListDelete
合并
已知 :有两个顺序表LA和LB,其元素均为非递减有序排列,编写一个算法,将它们合并成一个顺序表LC,要求LC也是非递减有序排列。
算法思想 :设表LC是一个空表,为使LC也是非递减有序排列,可设两个指针i、j分别指向表LA和LB中的元素,若LA.elem[i]>LB.elem[j],则当前先将LB.elem[j]插入到表LC中,若LA.elem[i]≤LB.elem[j] ,当前先将LA.elem[i]插入到表LC中,如此进行下去,直到其中一个表被扫描完毕,然后再将未扫描完的表中剩余的所有元素放到表LC中。
void merge(SeqList *LA, SeqList *LB, SeqList *LC) //有序表合并
{
int i=0,j=0,k=0; //预定义三个变量,表示LA、LB、LC中元素序号
while(i<=LA->length&&j<=LB->length) //LA、LB均不空时
if(LA->data[i]<=LB->data[j]) //如果LA中元素小于LB中元素
{
LC->data[k]= LA->data[i];
i++; k++;
} //将LA中元素插入LC
else //否则将LB中元素插入LC
{
LC->data[k]=LB->data[j];
j++; k++;
}
while(i<=LA->length) /*当表LA有剩余元素则将余下的元素赋给表LC*/
{
LC->data[k]= LA->data[i];
i++; k++; }
while(j<=LB->length)/*当表LB有剩余元素则将余下的元素赋给表LC*/
{
LC->data[k]= LB->data[j];
j++; k++;
}
LC-> length =LA-> length +LB-> length+1; //最后将表C长度赋值
}
动态线性表
结构体
typedef struct Seqlist
{
/* data */
ELEMTYPE *data;
ELEMTYPE MaxSize; //顺序表最大容量
ELEMTYPE length; //顺序表当前长度
} SeqList;
- 调用方式同静态
动态分配,初始化
void InitSeqList(SeqList * L)
{
L->data = (ELEMTYPE *)malloc(INITSIZE * sizeof(ELEMTYPE));
L->length = 0;
L->MaxSize = INITSIZE;
}
增加动态数组的长度
>len:需要增加的长度
void IncreaseSize(SeqList * L, int len)
{
ELEMTYPE *p = L->data; //存放改变之前的数据
L->data = (ELEMTYPE *)malloc((L->MaxSize + len) * (sizeof(ELEMTYPE)));
for (int i = 0; i < L->length; i++)
{
L->data[i] = p[i]; //旧数据复制到新区域
}
L->MaxSize = L->MaxSize + len;
free(p); //释放原来的内存空间
}
- 动态线性表操作方式思路基本与静态线性表相同,可直接参考
代码文件放在码云上,需要请自取:链接