线性结构
线性结构的特点
线性表为一种线性结构,线性结构所具有的特点:在数据元素的非空有限集中
(1)存在唯一的一个被称作“第一个”的数据元素;
(2)存在唯一的一个被称作“最后一个”的数据元素;
(3)除第一个之外,集合中每个数据元素均只有一个前驱;
(4)除最后一个之外,集合中每个数据元素均只有一个后继。
前驱和后继
若线性表记为(a1,…,ai-1,ai,ai+1,…,an)
则ai-1为ai的前驱也称直接前驱,ai+1为ai的后继也称直接后继。
线性表
线性表是一种最简单的数据结构,一个线性表是N个数据元素的有限序列。
在复杂的线性表中,一个数据元素可有若干数据项组成。
线性表的基本操作(顺序表示)
//基本定义操作
#define LIST_INIT_SIZE 100 //存储空间的初始分配量
#define LISTINCREMENT 10 //存储空间的分配增量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define ElemType int
#define UNDEFINE 1e5+5
typedef int Status;
定义线性表的动态分配顺序存储结构
//线性表的动态分配顺序存储结构
typedef struct SqList
{
ElemType *elem;
int length;
int Listsize;
};
InitList 构造一个空的线性表
Status InitList(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;
}
DestroyList 销毁线性表L
Status DestoryList(SqList &L)
{
//销毁线性表L
if(L.elem)free(L.elem);
}
将L重置为空表
Status ClearList(SqList &L)
{
L.length = 0;
return OK;
}
判断线性表是否为空,为空返回TRUE,否则返回FALSE
Status ListEmpty(SqList L)
{
if(L.length == 0)return TRUE;
else return FALSE;
}
返回L中的元素个数
Status ListLength(SqList L)
{
return L.length;
}
用e返回L中第i个数据元素的值
Status GetElem(SqList L,int i,ElemType &e)
{
if(L.length==0||i<1||i>L.length)return ERROR;
*&e= L.elem[i-1];
return OK;
}
返回L中第一个与e满足关系compare的数据元素的位序,若这样的元素不存在则返回0
bool compare(int a,int b)
{
if(a==b)return true;
else return false;
}
Status LocateElem(SqList L,int e)
{
if(L.length == 0)return 0;
for(int i=0;i<L.length;i++)
{
if(compare(L.elem[i],e))return i+1;
}
return 0;
}
用pre_e犯规cur_e的前驱,若不存在则pre_e无定义
Status PriorElem(SqList L,int cur_e,int &pre_e)
{
int now = LocateElem(L,cur_e);
if(now==0||now ==1)return ERROR;
else
{
pre_e = L.elem[now-2];
return TRUE;
}
}
用next_e返回cur_e的后继,若不存在pre_e无定义
Status NextElem(SqList L,int cur_e,int &next_e)
{
int now = LocateElem(L,cur_e);
if(now == 0 || now == L.length)return ERROR;
else
{
next_e = L.elem[now];
return TRUE;
}
}
在L中第i个位置之前插入新的数据元素e,L的长度加一
Status ListInsert(SqList &L,int i,ElemType e)
{
ElemType *newbase;
ElemType *p,*q;
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返回其值,L的长度减1
Status ListDelete(SqList &L,int i,ElemType &e)
{
ElemType *p,*q;
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;
}
对L的没个数据元素调用函数visit()
void visit(int data)
{
printf("%d ",data);
}
Status ListTraverse(SqList L)
{
for(int i=0;i<L.length;i++)
{
visit(L.elem[i]);
}
printf("\n");
return OK;
}
将所有在Lb中不在La中的元素插入到La
void union1(SqList &La,SqList Lb) //时间复杂度Len_la*Len_lb
{
int Len_la = ListLength(La);
int Len_lb = ListLength(Lb);
for(int i=1 ;i <= Len_lb;i++)
{
int e;
GetElem(Lb,i,e);
if(!LocateElem(La,e))ListInsert(La,++Len_la,e);
}
}
void union2(SqList &La,SqList Lb)
{
/*先用map对La中的数据进行标记,再对Lb中数据进行扫描,将存在Lb中不存在La中的数据插入到La,同时map标记该数据*/
map<int,bool>mp;
int Len_la = ListLength(La);
int Len_lb = ListLength(Lb);
for(int i=1;i<=Len_la;i++)
{
int e;
GetElem(La,i,e);
mp[e] = true;
}
for(int i=1;i<=Len_lb;i++)
{
int e;
GetElem(Lb,i,e);
if(mp[e] == false)ListInsert(La,++Len_la,e),mp[e]=true;
}
}
归并有序线性表La,Lb将结果存在Lc中
void MergeList(SqList La,SqList Lb,SqList &Lc)
{
int nowa=1,nowb=1;
int nowc=1;
while(nowa<=La.length&&nowb<=Lb.length)
{
int e1,e2;
GetElem(La,nowa,e1);
GetElem(Lb,nowb,e2);
if(e1<=e2)ListInsert(Lc,nowc++,e1),nowa++;
else ListInsert(Lc,nowc++,e2),nowb++;
}
while(nowa<=La.length)
{
int e;
GetElem(La,nowa,e);
ListInsert(Lc,nowc++,e);
nowa++;
}
while(nowb<=Lb.length)
{
int e;
GetElem(Lb,nowb,e);
ListInsert(Lc,nowc++,e);
nowb++;
}
}
主函数
int main()
{
SqList La,Lb,Lc;
InitList(La);
InitList(Lb);
InitList(Lc);
}
线性表链式实现
待更新。。。。。