实验一 线性表的顺序实现及操作

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一 线性表的顺序实现及操作
一、实验目的
1.掌握用上机调试线性表顺序实现的基本方法。

2.掌握线性表的基本操作,插入、删除、查找等运算在顺序存储结构上的实现。

二、实验要求
1.认真阅读和分析实验内容。

2.设计顺序线性表操作的算法。

3.编程实现这些算法。

4.上机调试程序,结合程序进行分析,打印出文件清单和运行结果。

三、实验内容
1.线性表顺序存储的物理结构(如图所示)
① Elem :存储存放表元素连续内存空间的首地址;
② Length :存储Elem 所指空间中存放的元素个数;
③ ListSize :存储Elem 空间的大小,该大小值以元素个数为单位来体现;
④ 注意,在线性表的逻辑结构中,元素在线性表中的位置次序是从1开始计数的; ⑤ 线性表L 实质是一个具有三个域的结构类型的变量。

2.编程实现如下要求:
定义出该线性表物理结构;初始化顺序存储的线性表;销毁线性表;将线性表重新设置为空表;判断线性表是否为空表;返回线性表的长度;在线性表中插入一个元素;在线性表中删除一个元素;取线性表中第i 个元素的值;在线性表中查找参数Elem 值所给定的元素;将线性表中指定位置的元素值修改成指定的值。

3.代码示例
// 以下代码书写在SqList.h 文件中。

#include <stdlib.h> // 一般将系统头文件用< >括起来,自定义头文件用" "括起来。

#define LIST_INIT_SIZE 50
#define LIST_INCREMENT 50
//typedef int ListElemType;
// 该类型的定义也可以在该头文件的外部来定义,这样在使用线性表结构时,可以尽可能少地 // 改动该头文件内的代码。

// 顺序线性表数据类型的定义。

该定义是对所设计的物理结构的编程语言描述。

typedef struct
{
ListElemType *Elem; // 存放一片连续内存空间的首地址,该空间中存放线性表元素值。

unsigned long Length; // 存放线性表中元素的个数值。

unsigned long ListSize; // 存放Elem 对应空间的大小,该大小用元素的个数来体现。

} List, SqList;
// List 类型和SqList 类型相同,都是包含三个域的结构类型。

但语义不同,List 表示线性表,SqList // 表示顺序存储结构的线性表。

L
void InitList(SqList &L) // 初始化线性表,即建立空表。

也就是说,Elem有空间,但无元素。

{
L.Elem = (ListElemType *)malloc(LIST_INIT_SIZE * sizeof(ListElemType));
if(L.Elem == NULL) exit(OVERFLOW); //申请Elem对应的内存空间用以存放线性表元素。

L.Length = 0; // 设置线性表中无元素,即空表。

L.ListSize = LIST_INIT_SIZE; // 记录Elem所对应空间的大小。

return;
}
void DestroyList(SqList &L) // 销毁线性表,即释放Elem对应的内存空间。

{
free(L.Elem); // 释放Elem所对应的内存空间。

L.Elem = NULL; //由于Elem不再对应内存空间,此时设置该指针变量为NULL是一个好习惯。

L.Length = L.ListSize = 0; // 设置两者为0,使得数据的物理存储值与语义一致。

return;
}
void ClearList(SqList &L) // 将线性表重新设置为空表。

{
free(L.Elem);
InitList(L);
return;
}
Status ListEmpty(SqList L) // 判断线性表是否为空表。

若是空表返回TRUE,否则返回FALSE。

{
if(L.Length == 0) // Length的值为0表示线性表为空,即表中无元素。

return TRUE;
else
return FALSE;
}
unsigned long ListLength(SqList L) // 返回线性表的长度,即线性表中元素的个数。

{
return L.Length;
}
// 在线性表中第i个元素之前插入一个新元素NewElem。

i的范围从1到表长加1。

// 线性表中元素的顺序从1开始计数,这比较符合人类的思维。

但C中数组元素的计数往往从0开始。

Status ListInsert(SqList &L, unsigned long i, ListElemType NewElem)
{
// 检查参数i的合法性。

// 由于插入一个元素,故线性表的长度加1。

// 此时由于表中元素已经将Elem对应的内存空间占满,故需要扩大该空间以容纳更多的表元素。

// 将Elem空间中第i个元素之后的所有元素依次向后移动。

// 将新插入的元素添加到表中第i个位置,以实现元素插入操作。

return OK;
}
// 通过以上代码,Elem所指的连续存储区域可以通过一维数组的方式来进行访问,而不必使用指针// 的方式,这样代码的逻辑更清晰。

Status ListGetElem(SqList L, unsigned long i, ListElemType &Elem)
{
// 取线性表中第i个元素的值,该元素值由函数的Elem参数输出。

函数返回值为OK时表示操作成功。

if(i < 1 || i > L.Length) return ERROR;
Elem = L.Elem[i-1]; // Elem数组中下标为i-1的元素即为线性表中的第i个元素。

return OK;
}
// 在线性表中查找参数Elem值所给定的元素,若该值是线性表中的元素,则返回该元素所在表中
// 的位置;若在线性表中不存在该元素,则返回0。

unsigned long ListLocateElem(SqList L, ListElemType Elem)
{
// 在表中从第1个元素开始进行顺序地查找。

// 当没有满足循环终止条件而通过break跳出时,则说明找到了该元素。

}
Status ListGetPriorElem(SqList L, ListElemType CurElem, ListElemType
&PriorElem)
{ // 在线性表中找出参数CurElem值所代表元素的直接前驱元素,结果由参数PriorElem输出。

unsigned long CurElemPos = ListLocateElem(L, CurElem); // 在线性表中查找。

if(CurElemPos == 0 || CurElemPos == 1) //CurElemPos为0说明表中无CurElem元素;
return ERROR; // CurElemPos为1说明CurElem是表中第1个元素,无前驱。

else
{
PriorElem = L.Elem[CurElemPos - 2];
return OK;
}
}
Status ListGetNextElem(SqList L, ListElemType CurElem, ListElemType
&NextElem)
{ // 在线性表中找出CurElem参数所代表元素的直接后继元素,结果由参数NextElem输出。

unsigned long CurElemPos = ListLocateElem(L, CurElem);
if(CurElemPos == 0 || CurElemPos == L.Length)
return ERROR;// CurElemPos等于Length,说明CurElem是表中最后一个元素,无后继。

else
{
NextElem = L.Elem[CurElemPos];
return OK;
}
}
Status ListDelete(SqList &L, unsigned long DelPos, ListElemType &DelElem) { // 在线性表中删除第DelPos个位置的元素,同时将删除的元素值由参数DelElem输出。

// Elem数组中下标为DelPos-1的元素即为要删除的元素。

// 将第DelPos之后的元素依次前移一个元素位置。

// 线性表的元素个数减1。

{ // 由于在表中删除元素,若此时Elem所指向的空间可以进一步缩小,则重新申请新的小空间。

}
return OK;
}
void ListTraverse(SqList L)
{ // 正向遍历线性表,即从线性表中的第1个元素开始顺序地向后依次输出表中的全部元素值。

for(unsigned long i = 1; i <= L.Length; ++i)
printf("%d,", L.Elem[i-1]);
// 此处,表元素为整型数据。

可根据需要进行修改。

return;
}
void ListReverseTraverse(SqList L)
{ // 逆向遍历线性表,即从线性表中最后的元素开始顺序地向前依次输出表中的全部元素值。

for(unsigned long i = L.Length; i >= 1; --i)
printf("%d,", L.Elem[i-1]);
return;
}
Status ListModifyElem(SqList L, unsigned long Pos, ListElemType Elem)
{ // 将线性表中第Pos个的元素值修改成参数Elem的值。

if(Pos < 1 || Pos > L.Length) return ERROR;
L.Elem[Pos - 1] = Elem;
return OK;
}。

相关文档
最新文档