前提代码
#include <iostream>
using namespace std;
const int MAXSIZE = 20
typedef struct
{
int data[MAXSIZE];
int length;
}SqList;
打印整数
bool visit(int c) //ElemType c表示这个函数接收一个类型为ElemType的参数c,Status表示这个函数返回一个Status类型的值。
{
cout << c;
return true;
}
初始化顺序线性表
bool InitList(SqList *L)
{
L->length = 0;
return true;
}
int main()
{
SqList myList;
bool initStatus = InitList(&myList);
//调用InitList函数,并将myList的地址作为参数传递给函数。初始化的结果存储在initStatus变量中。
//initStatus变量用于存储InitList函数的返回值,以便在main函数中检查初始化的状态
if (initStatus == true)
{
cout<<"List initialized successfully.\n";
}
else
{
cout<<"Failed to initialize the list.\n";
}
return 0;
}
//在这段代码中,myList和L都是SqList类型的变量,但它们在不同的上下文中使用。
//1. myList是在主函数中声明的变量,用于表示一个具体的顺序表对象。它是主函数的局部变量,
//用于存储顺序表的数据。
//2. L是InitList函数的参数,它是一个SqList类型的指针。在函数调用时,将myList的地址传递给L,
//这样函数可以通过指针修改myList所指向的顺序表对象的属性。在InitList函数内部,使用L->length
//来访问顺序表的长度属性,并将其设置为0,实现了初始化操作。
//总结起来,myList是主函数中的顺序表对象,而L是InitList函数中用于接收顺序表对象地址的参数。
//通过将myList的地址传递给L,函数可以对myList进行初始化操作。
`Status initStatus = InitList(&myList);` 这行代码做了两件事:
1. 调用了 `InitList` 函数,并将 `myList` 的地址(通过 `&` 符号获取)作为参数传递。这是因为 `InitList` 函数需要一个指向 `SqList` 结构体的指针作为参数,所以我们需要传递 `myList` 的地址。
2. 将 `InitList` 函数的返回值(一个 `Status` 类型的值)赋值给了 `initStatus` 变量。这个返回值表示 `InitList` 函数执行的结果,如果返回 `OK`(定义为 `1`),则表示函数执行成功。
所以,这行代码的目的是调用 `InitList` 函数来初始化 `myList`,并检查函数执行的结果是否成功。
顺序线性表L已存在,判定是否空表
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
bool ListEmpty(SqList L)
{
if(L.length == 0)
return true;
else
return false;
}
int main()
{
SqList L;
int e;
if (InitList(&L)) //这行代码的含义是“如果初始化顺序表L成功,那么执行if后面的代码块”。
{
cout << "初始化后,L是否为空:" << (ListEmpty(L) ? "是" : "否") << endl;
for(int i = 1; i <= 5; i++)
ListInsert(&L, i, i);
cout << "插入1~5后,L是否为空:" << (ListEmpty(L) ? "是" : "否") << endl;
ListTraverse(L);
}
if (ListDelete(&L, 3, &e))
{
cout << "删除第3个元素后,L是否为空:" << (ListEmpty(L) ? "是" : "否") << endl;
ListTraverse(L);
}
return 0;
}
//为什么InitList函数用*L,ListEmpty函数用L ?
//InitList 函数的目的是初始化一个 SqList 对象,这涉及到修改对象的状态(在这种情况下,是修改 length 属性)。因此,我们需要传递一个指向 SqList 的指针* L,这样函数才能直接修改原始对象的状态。
//如果我们只传递 SqList 对象本身,函数将操作一个对象的副本,原始对象的状态将不会被改变。
//另一方面,ListEmpty 函数的目的是检查一个 SqList 对象是否为空,这并不需要修改对象的状态。因此,我们可以直接传递 SqList 对象 L。这样做的好处是可以避免使用指针,使代码更简单、更易于理解。
//`SqList *L`和`SqList L`的主要区别在于它们是不同类型的变量。`SqList *L`是一个指向`SqList`类型的指针,而`SqList L`是一个`SqList`类型的实例。
//当你使用`SqList* L`时,`L`是一个指向`SqList`类型的指针,你需要通过`- > `运算符来访问`SqList`中的成员,如`L- > length`。
//而当你使用`SqList L`时,`L`是一个`SqList`类型的对象,你可以直接通过`.`运算符来访问`SqList`中的成员,如`L.length`。
//两者的主要区别在于`SqList* L`可以动态地改变指向的对象,而`SqList L`在声明时就已经固定下来,不能改变。同时,指针`L`可以被设置为`NULL`,而对象`L`则始终会占用内存空间。
顺序线性表L已存在,将表重置为空表
bool ClearList(SqList *L)
{
L->length = 0;
return true;
}
int main()
{
SqList L;
int e;
if (InitList(&L))
{
for(int i = 1; i <= 5; i++)
ListInsert(&L, i, i);
cout << "插入1~5后,L中的元素为:";
ListTraverse(L);
}
if (ClearList(&L) == OK)
{
cout << "清空L后,L中的元素为:";
ListTraverse(L);
}
return 0;
}
返回线性表中数据元素个数
int ListLength(SqList L)
{
return L.length;
}
返回线性表中第i个数据元素的值
bool GetElem(SqList L,int i,int *e) //GetElem 是一个函数,接收一个 SqList 类型的值 L,一个整型值 i,以及一个指向 int 类型的指针 e 作为参数。它返回一个 Status 类型的值。
{
if(L.length == 0 || i < 1 || i > L.length)
return false;
*e = L.data[i-1]; //将 SqList L 中索引为 i-1 的元素值赋给指针 e 所指向的变量。
return true;
}
int main()
{
SqList L;
int e;
if (InitList(&L))
{
for(int i = 1; i <= 5; i++)
ListInsert(&L, i, i);
cout << "插入1~5后,L中的元素为:";
ListTraverse(L);
}
if (GetElem(L, 3, &e) == 1)
{
cout << "获取第3个元素的值为:" << e << endl;
}
return 0;
}
返回线性表中第1个与e满足关系的数据元素的位序
int LocateElem(SqList L,int e)
{
int i;
if (L.length == 0)
return false;
for(i = 0;i < L.length;i++)
{
if (L.data[i] == e)
break;
}
if(i >= L.length)
return false;
return i+1;
}
在线性表中第i个位置之前插入新的数据元素e,L的长度加1
bool ListInsert(SqList *L,int i,int e)
{
int k;
if (L->length == MAXSIZE) /* 顺序线性表已经满 */
return false;
if (i < 1 || i > L->length+1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */
return false;
if (i <= L->length) /* 若插入数据位置不在表尾 */
{
for(k = L->length-1;k >= i-1;k--) /* 将要插入位置之后的数据元素向后移动一位 */
L->data[k+1] = L->data[k];
}
L->data[i-1] = e; /* 将新元素插入 */
L->length++;
return true;
}
int main()
{
// 创建一个列表并添加一些元素
SqList list;
list.length = 5;
for (int i = 0; i < list.length; i++)
list.data[i] = i + 1;
// 插入一个元素
if (ListInsert(&list, 3, 10) == 1) //ListInsert(&list, 3, 10):这是对 ListInsert 函数的调用。函数的参数是一个指向 list 的指针(&list),一个整数 3(表示要插入元素的位置),和一个整数 10(表示要插入的元素)
cout<<"Element inserted successfully\n";
else
cout<<"Error inserting element\n";
return 0;
}
删除线性表的第i个数据元素,并用e返回其值,线性表的长度减1
#include <iostream>
using namespace std;
const int MAX_SIZE = 100;
struct SqList
{
int data[MAX_SIZE];
int length;
};
bool ListDelete(SqList& L, int i, int& e)
{
if (L.length == 0)
return false;
if (i < 1 || i > L.length)
return false;
e = L.data[i - 1]; //将顺序表中待删除元素的值保存到变量e中,以便在后续的输出中使用
if (i < L.length)
{
for (int k = i; k < L.length; k++)
{
L.data[k - 1] = L.data[k];
}
}
L.length--;
return true;
}
int main()
{
SqList list;
list.length = 5;
list.data[0] = 1;
list.data[1] = 2;
list.data[2] = 3;
list.data[3] = 4;
list.data[4] = 5;
cout << "Before deletion: ";
for (int i = 0; i < list.length; i++)
{
cout << list.data[i] << " ";
}
cout << endl;
int position = 3;
int deletedElement;
bool result = ListDelete(list, position, deletedElement);
if (result == true)
{
cout << "Element at position " << position << " (" << deletedElement << ") is deleted." << endl;
}
else
{
cout << "Deletion failed. Invalid position." << endl;
}
cout << "After deletion: ";
for (int i = 0; i < list.length; i++)
{
cout << list.data[i] << " ";
}
cout << endl;
return 0;
}
依次对线性表的每个数据元素输出
bool ListTraverse(SqList L)
{
int i;
for(i = 0;i < L.length;i++)
visit(L.data[i]);
cout<<" ";
return true;
}
int main()
{
// 创建一个列表并添加一些元素
SqList list;
list.length = 5;
for (int i = 0; i < list.length; i++)
list.data[i] = i + 1;
// 遍历列表
ListTraverse(list);
return 0;
}
将所有的在线性表Lb中但不在La中的数据元素插入到La中
void unionL(SqList *La,SqList Lb)
{
int La_len,Lb_len,i;
int e; /*声明与La和Lb相同的数据元素e*/
La_len = ListLength(*La); /*求线性表的长度 */
Lb_len = ListLength(Lb);
for (i = 1;i <= Lb_len;i++)
{
GetElem(Lb,i,&e); /*取Lb中第i个数据元素赋给e*/
if (!LocateElem(*La,e)) /*La中不存在和e相同数据元素*/
ListInsert(La,++La_len,e); /*插入*/
}
}
int main()
{
SqList L;
SqList Lb;
int e;
bool i;
int j,k;
i = InitList(&L);
cout<<"初始化L后:L.length=%d\n",L.length;
for(j = 1;j <= 5;j++)
i = ListInsert(&L,1,j);
cout<<"在L的表头依次插入1~5后:L.data=";
ListTraverse(L);
cout<<"L.length=%d \n",L.length;
i = ListEmpty(L);
cout<<"L是否空:i=%d(1:是 0:否)\n",i;
i = ClearList(&L);
cout<<"清空L后:L.length=%d\n",L.length;
i = ListEmpty(L);
cout<<"L是否空:i=%d(1:是 0:否)\n",i;
for(j = 1;j <= 10;j++)
ListInsert(&L,j,j);
cout<<"在L的表尾依次插入1~10后:L.data=";
ListTraverse(L);
cout<<"L.length=%d \n",L.length;
ListInsert(&L,1,0);
cout<<"在L的表头插入0后:L.data=";
ListTraverse(L);
cout<<"L.length=%d \n",L.length;
GetElem(L,5,&e);
cout<<"第5个元素的值为:%d\n",e;
for(j = 3;j <= 4;j++)
{
k = LocateElem(L,j);
if(k)
cout<<"第%d个元素的值为%d\n",k,j;
else
cout<<"没有值为%d的元素\n",j;
}
k = ListLength(L); /* k为表长 */
for(j = k+1;j >= k;j--)
{
i = ListDelete(&L,j,&e); /* 删除第j个数据 */
if(i == 0)
cout<<"删除第%d个数据失败\n",j;
else
cout<<"删除第%d个的元素值为:%d\n",j,e;
}
cout<<"依次输出L的元素:";
ListTraverse(L);
j = 5;
ListDelete(&L,j,&e); /* 删除第5个数据 */
cout<<"删除第%d个的元素值为:%d\n",j,e;
cout<<"依次输出L的元素:";
ListTraverse(L);
//构造一个有10个数的Lb
i = InitList(&Lb);
for(j = 6;j <= 15;j++)
i = ListInsert(&Lb,1,j);
unionL(&L,Lb);
cout<<"依次输出合并了Lb的L的元素:";
ListTraverse(L);
return 0;
}