2.1线性表的类型定义
1.定义:一个线性表是n个数据元素的有限序列。
2.线性表的元素个数n即为线性表的长度,当n=0时,称为空表
3.线性表的基本操作
InitList(&L)//构造一个空的线性表
DestoryList(&L)//销毁线性表
ClearList(&L)//将L重置为空表
ListEmpty(L)//判断是否为空表
ListLength(L)//判断线性表长度
GetElem(L,i,&e)//用e返回L中第i个元素的值
LocateElem(L,e,compare())//返回L中第一个与e相等元素的位置
PriorElem(L,cur_e,&pre_e)//若cur_e是L的数据元素,且不是第一个,则用pre_e返回他的前驱,否则操作失败
NextElem(L,cur_e,&next_e)//返回cur_e在L中的后继
ListInsert(&L,i,e)//zai线性表中的第i个位置插入e
ListDelete(&L,i,&e)//删除L的第i个数据元素,并用e返回其值。
eg1:实现A=AUB
void union(List &La,List Lb)
{
La_len = Listlength(La);
Lb_len = Listlength(Lb);
for( i = 0 ; i < = Lb-len ; i++)
{
GetElem(Lb , i , e);
if(!LocateElem(La , e, equal))
ListInsert(La ,++La_len , e);
}
}
eg2:LA和LB中的数据元素按照值递增排序,要求将LA和LB合并到一个新的线性表LC中,LC中的数据元素也是按照递增排序的。(不合并相同的元素)
void union(List La,List Lb , &Lc)
{
InitList(Lc);
int i = j = 1;
La_len = Listlength(La);
Lb_len = Listlength(Lb);
while((i<=La_len)&&(j<=Lb_len))
{
GetElem(La , i ,ai);
GetElem(Lb , j ,bj);
if(ai >= bj)
{
Insert(Lc , ++k , bj);
++j;
}else{
Insert(Lc , ++k , ai);
++i;
}
//当La,或者Lb有一方遍历完成后
while(i<=La_len){
GetElem(La , ++i ,ai);
ListInsert(Lc , ++k , ai);
}
while(j<=Lb_len){
GetElem(Lb , ++j ,bj);
ListInsert(Lc , ++k , bj);
}
}
}
2.2线性表的顺序表示和实现
1.定义:
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素
2.用代码实现一个可动态分配的线性表
#define SIZE 100
#define LISTINCREMENT 10;;
typedef struct{
ElemType *elem;
int length;
int listsize;
}SqList;
Status InitList_Sq(Sqlist &L)
{
//创建一个空的线性表
L.elem = (Elemtype *)malloc(SIZE*sizeof(Elemtype));
L.length = 0;//空表长度为0;
L.listsize = SIZE;//初始存储容量
}//创建容量为SIZE的空的线性表
//时间复杂度o(1);
malloc的语法是:指针名=(数据类型*)malloc(长度),(数据类型*)表示指针
3.线性表的插入操作-----ListInsert(&L, i, e)
Status ListInsert_Sq(SqList &L, int i,ElemType e)
{
//在顺序表的第i个元素之前插入 e元素;
//i的合法范围为 1=<i<=L.length+1;
if(i<1||i>L.length+1)
return error;
if(L.length>=L.listsize)//当前空间已满,增加分配
{
newbase = (ElemType *)realloc(L.elem , (List.LiseSize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW);//存储空间分配失败
L.elem = newbase; //新基址
L.listsize + =LISTINCREMENT;
}
q = &(L.elem[L.length-1]);//q为插入位置
//插入的以及之后的位置后移一位
for(p = &(L.elem[L.length-1]); p >=q ; p--)
{
*(p+1)=*p;
}
*q = e;//插入e
++L.length;//表长增加一
return OK;
}
4线性表的删除操作
Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{ // 在顺序表L中删除第 i 个元素,并用e返回其值, // i 的合法范围为 1≤i≤L.length
if ((i < 1) || (i > L.length)) return ERROR; // i值不合法
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 ; // 表长减1
return OK ;
} // ListDelete_Sq
5.线性表的查找函数
int LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType , ElemType ))
{
//在线性表L中查找第1个与e满足conpare()元素的位序
//找到返回0,未找到返回1
i = 1;
p = L.elem;
while(i<=L.length && !(* compare)(*p++ ,e)){
++i;
}
if (i<=L.length) {
return i;
}else
return 0;
}
6.eg2另解
void MergeList _Sq(SqList La, SqList Lb, SqList &Lc) {
//已知线性表La 和Lb中数据元素按值非递减有序排列
//归并La 和Lb得到新的线性表Lc,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 )
*pc++ = *pa++; //插入La的剩余元素
while ( pb<= pb_last ) *pc++ = *pb++; //插入Lb的剩余元素
} // MergeList _Sq