最近在看数据结构,所以就当是整理吧,写下来,方便自己以后查看!
线性表是最简单且最常用的一种数据结构,首先我们来看一下线性表的动态分配顺序存储结构
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
说完结构,我们再来看看线性表的初始化。
Status InitList_Sq(SqList &L)
{//构造一个空的线性表L
L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) //存储分配失败
exit(OVERFLOW);
L.length = 0; //空表长度为0
L.listsize = LIST_INIT_SIZE; //初始化存储容量
return OK;
}
这就是线性表的初始化了,线性表的主要作用是插入和删除操作,下面来看一下:
首先来看一下插入操作:
Status ListInsert_Sq(SqList &L, int i, ElemType e)
//在顺序线性表L中第i个位置之前插入新的元素e
{
if(i < 1 || i>L.length + 1) //检验i的合法性
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]); //q为插入的位置
for(p = &(eL.elem[L.length - 1]; p >= q; --p)
*(p+1) = *p;//插入位置及之后的元素右移
*q = e; //插入e
++L.length;//表长加1
return OK;
}
插入的基本思想是:找到插入的位置,插入位置及以后的数往后移,给第i个位置赋值e;
再来看看删除操作:
Status ListDelete_Sq(SqList &L,int i, ElemType &e)
{
if((i < 1) || (i > L.length)) //i是否合法
return ERROR;
p = &(L.elem[i-1]); //p为删除元素的位置
e = *p; //被删除元素的值赋给e
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 = pb.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++;
}
线性顺序表的操作差不多就这些了,写了好久,休息,休息。。