数据结构C语言版.线性表的动态分配顺序存储结构表示和实现文库 下载本文

/*

数据结构C语言版 线性表的动态分配顺序存储结构表示和实现 编译环境:Dev-C++ */

#include #include #include

typedef int ElemType; // 定义数据结构元素的数据类型

#define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量 #define LISTINCREMENT 5 // 线性表存储空间的分配增量

// 线性表的动态分配顺序存储结构 typedef struct {

ElemType *elem; // 存储空间基址 int length; // 当前长度

int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位) }SqList;

// 算法2.3,P23

// 构造一个空的顺序线性表即对顺序表结构体中的所有元素 // 进行初始化。

int InitList(SqList *L) {

// 分配指定大小的存储空间给顺序表

(*L).elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if( !(*L).elem ) // 存储分配失败 exit(0);

(*L).length = 0; // 当前长度初始化为0 // 指定分配的存储容量

(*L).listsize = LIST_INIT_SIZE;

return 1; }

// 销毁顺序线性表L即将顺序表结构体中的所有成员销毁(空间释放, // 数值置0)。

int DestroyList(SqList *L) {

// 先释放空间,然后置空 free( (*L).elem );

(*L).elem = NULL;

(*L).length = 0; (*L).listsize = 0;

return 1; }

// 将L重置为空表(当前长度为0即是空表)。 int ClearList(SqList *L) {

(*L).length = 0;

return 1; } /*

若L为空表,则返回1,否则返回0。

如何判断是否为空表呢?结构体中已经包含一个可以说明的元素, 那就是length,表示当前顺序表的长度,根据当前的长度就可以 判断了,为0就是空表,不为0就不是空表了。 */

int ListEmpty(SqList L) {

if(0 == L.length) return 1; else

return 0; }

// 返回L中数据元素个数。 int ListLength(SqList L) {

// L.length刚好记录了当前顺序表的长度,直接返回 return L.length; }

// 用e返回L中第i个数据元素的值,第i个数据元素就是L.elem[i-1]。 int GetElem(SqList L,int i,ElemType *e) {

// 首先进行异常处理

if(i < 1 || i > L.length) exit(0);

/*

注意顺序表基址L.elem[0] 表示第一个数,而第i个数则是用 基址L.elem + i - 1来表示,也可以用L.elem[i-1]表示。为什么 可以那样表示呢?因为l.elem是基地址,相当于数组头一样,指 示了一个首地址,然后对地址进行加减,形成不同元素的地址。 *是取地址所指的内容,所以*(L.elem+i-1)就是第i个数据的值了。 */

*e = *(L.elem + i - 1); // *e = L.elem[i-1];

return 1; }

/* 算法2.6,P26

返回L中第1个与e满足关系compare()的数据元素的位序。 若这样的数据元素不存在,则返回值为0。 */

int LocateElem(SqList L,ElemType e,

int(* compare)( ElemType, ElemType)) {

ElemType *p;

int i = 1; // i的初值为第1个元素的位序

p = L.elem; // p的初值为第1个元素的存储位置即地址

// 循环比较,直到找到符合关系的元素

while(i <= L.length && !compare(*p++, e) ) ++i;

if(i <= L.length) return i; else

return 0; }

#if 0

/* 算法2.7 与算法2.2区别

已知顺序线性表La和Lb的元素按值非递减排列。归并La和Lb得到新的顺序 线性表Lc,Lc的元素也按值非递减排列。

算法的时间复杂度为O(La.length + Lb.length). */

void MergeList(SqList La, SqList Lb, SqList *Lc) {

ElemType *pa, *pa_last, *pb, *pb_last, *pc;

pa = La.elem; //pa指向线性表La的头结点

pb = Lb.elem; //pb指向线性表Lb的头结点 /* 不用InitList()创建空表Lc */

(*Lc).listsize = (*Lc).length = La.length + Lb.length; // pc指向线性表Lc的头结点 pc = (*Lc).elem =

(ElemType *)malloc((*Lc).listsize*sizeof(ElemType)); if( !(*Lc).elem ) /* 存储分配失败 */ exit(0);

pa_last = La.elem + La.length - 1; //pa_last指向线性表La的尾结点 pb_last = Lb.elem + Lb.length - 1; //pb_last指向线性表Lb的尾结点 while(pa <= pa_last && pb <= pb_last) /* 表La和表Lb均非空 */ { /* 归并 */

if(*pa <= *pb) //*pa更小接到pc后 *pc++ = *pa++;

else //*pb更小接到pc后 *pc++ = *pb++; }

while(pa <= pa_last) /* 表La非空且表Lb空 */ *pc++ = *pa++; /* 插入La的剩余元素 */ while(pb <= pb_last) /* 表Lb非空且表La空 */ *pc++ = *pb++; /* 插入Lb的剩余元素 */ }

#endif

// 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否 // 则返回0。

int PriorElem(SqList L, ElemType cur_e, ElemType *pre_e) {

int i = 2;

// 因为第一个数据元素无前继,从第二个数据元素开始 ElemType *p = L.elem + 1;

// 找到该cur_e对应的元素并赋给p while(i <= L.length && *p != cur_e) {

p++; i++; }

if(i > L.length) return 0; else {

/*

将该cur_e的前驱赋给*pre_e.