线性结构的基本特点是:在数据元素的非空有限集合中,除第一个元素无直接前驱、最后一个元素无直接后继外,集合中其他每个数据元素均有唯一的直接前驱和直接后继。
线性表是由n个类型相同的数据元素组成的有限序列。
矩阵、数组、字符串、堆栈、队列都符合线性条件,都属于线性表。
线性表有两种基本的存储结构:顺序存储结构和链式存储结构。
1.顺序表
通过数据元素物理存储的连续性来反映数据元素之间逻辑上的相邻关系,LOC(ai)=LOC(a1)+(i-1)*l(每个元素占用l个存储单元)。线性表中任意数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。由于线性表的长度可变,且所需的最大存储空间随问题不同而不同,在C语言中可用动态分配的一位数组来描述顺序表。
//----------------线性表的动态分配顺序存储结构-----------------------
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
//----------------构造一个空的线性表L-----------------------
Status InitList_Sq(SqList &L){
L.elem = (ElemType * )malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)
exit(OVERFLOW);
L.length = 0;
L.listsize = LIST_INIT_SIZE; //初始存储容量
return OK;
}
//----------------在顺序表L中第i个位置之前插入一个元素e-----------------------
Status ListInsert_Sq(SqList &L, int i, ElemType e){
if (i < 1 || i > L.length + 1)
return ERROR;
if (L.length >= L.listsize){ //存储空间已满,增加分配
newbase = (ElemType *)realloc(L.elem,(L.listsize + LISTINCREMENT) * sizeof(ElemType));
if (! newbase)
exit(OVERFLOW);
L.elem = newbase; //新基址
L.listsize += LISTINCREMENT;
}
q = & (L.elem[i-1]);
for (p = &(L.elem[L.length - 1]); p >= q; --p)
*(p + 1) = *p; //插入位置及之后的元素右移
*q = e;
++L.length;
return OK;
}
//----------------在顺序表L中删除第i个位置,并用e返回其值-----------------------
Status ListDelete_Sq(SqList &L, int i, ElemType &e){
if ((i < 1) || (i > L.length))
return ERROR;
p = & (L.elem[i - 1]);
e = * p;
q = L.elem + L.length - 1; //表尾元素的位置
for (++p; p <= q; ++p)
* (p - 1) = * p;
--L.length;
return OK;
}
线性表插入和删除的时间复杂度为O(n)。
//----------------已知顺序线性表La和Lb的元素按值非递减排列---------------------
//----------------归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列---
void MergeList_Sq(SqList La, SqList Lb, SqList &Lc){
pa = La.elem;
pb = Lb.elem;
Lc.listsize = Lc.length = La.length + Lb.length;
pc = Lc.elem = (ElemType *)malloc(Lc.listsize * sizeof(ElemType));
if (!Lc.elem)
exit (OVERFLOW);
pa_last = La.elem + La.length - 1;
pb_last = Lb.elem + Lb.length - 1;
while (pa <= pa_last && pb <= pb_last){ //归并
if (*pa <= *pb)
*pc++ = *pa++;
else
*pc++ = *pb++;
}
while (pa <= pa_last) //插入La的剩余元素
*pc++ = *pa++;
while (pb <= pb_last) //插入Lb的剩余元素
*pc++ = *pb++;
return OK;
}
线性表归并的时间复杂度为O(La.length + Lb.length)。
线性表的顺序表示和插入、删除、归并C语言代码实现
http://download.youkuaiyun.com/source/2158379