顺序线性表的实现
顺序线性表的实现
/*
* AUTHOR BNTU
* TIME 2021年2月25日15:35:17
* TITLE 顺序表的定义.cpp
* ABSTRACT (1)、顺序表的插入和删除操作的时间复杂度都是o(n),存取元素的时间复杂度为o(1);
* (2)、顺序表的优点:
* ①、无须为表示表中元素之间的逻辑关系而增加额外的存储空间;【顺序表逻辑相邻的同时物理上也相邻】
* ②、可以快速地存取表中任意位置的元素;【顺序表随机存取】
* (3)、顺序表的缺点:
* ①、插入和删除操作需要移动大量的元素;
* ②、当线性表长度变化较大时,存储空间的容量不稳定,造成realloc函数频繁使用;
* ③、由于都是占用连续的大块地址,所以容易产生存储空间的“碎片”;
*/
#include<iostream>
#include"../../全局定义/预定义常量和类型/预定义常量和类型.cpp"
#include"../../全局定义/Compare函数的定义/Compare函数的定义.cpp"
#define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量;
#define LIST_INCREMENT 10 // 线性表存储空间的分配增量;
#define ElemType int
using namespace std;
typedef struct {
ElemType* list; // 顺序表(数组)的指针;
int length; // 顺序表的长度(现有的元素个数);
int listSize; // 存储容量;
}SqList, * P_SqList; // sequence list: 顺序列表
// 初始化顺序表
Status InitSqList(P_SqList& sqList, int size = LIST_INIT_SIZE) {
// 构造一个空的线性表sqList
sqList->list = (ElemType*)malloc(size * sizeof(ElemType));
if (!(sqList->list)) {
exit(OVERFLOW);
}
else
{
sqList->length = 0;
sqList->listSize = size;
return OK;
}
}
// 在顺序表的第order个位置插入元素elem
Status InsertSqList(P_SqList& sqList, int order, ElemType elem) {
// 判断order的合法性: [1, length+1]
if (1 <= order && order <= sqList->length + 1) {
// 判断表长是否在安全范围之内(存储空间是否爆满)
if (sqList->length >= sqList->listSize) {
ElemType* newBase =
(ElemType*)realloc(
sqList->list,
(sqList->listSize + LIST_INCREMENT) * sizeof(ElemType));
// 判断是否重新开辟成功
if (newBase) {
sqList->list = newBase;
sqList->listSize += LIST_INCREMENT;
}
else
{
exit(OVERFLOW);
}
}
// 索引指向末尾
ElemType* index = &sqList->list[sqList->length - 1];
// 直至循环到索引指向第order个位置,并让该位置向后移动一位
while (index >= &sqList->list[order - 1])
{
// 将元素想右移动一位;
*(index + 1) = *index;
index--;
}
sqList->list[order - 1] = elem;
sqList->length++;
return OK;
}
else
{
return ERROR;
}
}
// 在顺序表的第order个位置删除元素elem
Status DeleteSqList(P_SqList& sqList, int order, ElemType& elem) {
// 判断order的合法性: [1, length]。当length为0时任何order不成立。
if (1 <= order && order <= sqList->length)
{
// 用elem接收即将被删除的元素
elem = sqList->list[order - 1];
ElemType* index = &sqList->list[order];
while (index < &sqList->list[sqList->length])
{
// 将元素向左移动一位
*(index - 1) = *index;
index++;
}
sqList->length--;
}
else
{
return ERROR;
}
}
// 获取顺序表的第order个位置的elem
Status GetSqListElem(P_SqList sqList, int order, ElemType& elem) {
// 判断order的合法性: [1, length]
if (1 <= order && order <= sqList->length) {
elem = sqList->list[order - 1];
return OK;
}
else
{
return ERROR;
}
}
// 打印出顺序表中的所有元素
Status PrintSqList(P_SqList sqList) {
ElemType elem;
Status status = ERROR;
for (int order = 1; order <= sqList->length; order++)
{
status = GetSqListElem(sqList, order, elem);
if (status != OK)
{
break;
}
cout << elem << " ";
}
cout << endl;
return status;
}
// 查找出第一个符合compare函数的elem的位置,找不到弹出-1
Status LocateSqListElem(P_SqList sqList, ElemType elem, int (*compare)(ElemType, ElemType), int& order) {
ElemType elem_get = NULL;
Status status = ERROR;
order = -1;
for (int order_tmp = 1; order_tmp <= sqList->length; order_tmp++)
{
if (GetSqListElem(sqList, order_tmp, elem_get) != OK)
break;
if (compare(elem_get, elem))
{
order = order_tmp;
status = OK;
break;
}
}
return status;
}
// 拷贝表(深拷贝)
Status CopySqList(P_SqList sqList_source, P_SqList& sqList_dest) {
delete sqList_dest;
sqList_dest = (P_SqList)new(SqList);
InitSqList(sqList_dest);
ElemType elem;
Status status = ERROR;
for (int order = 1; order <= sqList_source->length; order++)
{
status = GetSqListElem(sqList_source, order, elem);
if (status != OK)
break;
status = InsertSqList(sqList_dest, order, elem);
if (status != OK)
break;
}
return status;
}
// 替换第order个位子上的元素为elem
Status ReplaceSqListElem(P_SqList& sqList, int order, ElemType elem) {
// 判断order的合法性: [1, length]
if (1 <= order && order <= sqList->length) {
sqList->list[order - 1] = elem;
return OK;
}
else
{
return ERROR;
}
}
// 将顺序表反向
Status ReverseSqList(P_SqList& sqList) {
ElemType lowElem, highElem;
Status status = ERROR;
for (int order = 1; order <= sqList->length / 2; order++)
{
status = GetSqListElem(sqList, order, lowElem);
if (status != OK)
break;
status = GetSqListElem(sqList, sqList->length - order + 1, highElem);
if (status != OK)
break;
status = ReplaceSqListElem(sqList, order, highElem);
if (status != OK)
break;
status = ReplaceSqListElem(sqList, sqList->length - order + 1, lowElem);
if (status != OK)
break;
}
return status;
}
// 合并两个顺序表: A = A∪B
Status UnionSqList(P_SqList& sqListA, P_SqList sqListB) {
ElemType elem_B;
int order_A;
Status status = ERROR;
for (int order_B = 1; order_B <= sqListB->length; order_B++)
{
status = GetSqListElem(sqListB, order_B, elem_B);
if (status != OK)
break;
if (LocateSqListElem(sqListA, elem_B, Equal, order_A) != OK)
{
InsertSqList(sqListA, sqListA->length + 1, elem_B);
}
}
return status;
}
// 按照非递减或者非递增的方式合并两个顺序表
Status MergeSqList(P_SqList sqListA, P_SqList sqListB, P_SqList& sqListC, int (*compare)(ElemType, ElemType)) {
if (sqListC)
delete sqListC;
sqListC = (P_SqList)new(SqList);
if (!sqListC)
exit(OVERFLOW);
// 必须要开辟 sqListA->length + sqListB->length 这么大的内存空间,否则会造成内存泄露!
InitSqList(sqListC, sqListA->length + sqListB->length);
sqListC->length = sqListA->length + sqListB->length;
ElemType* pa = sqListA->list, * pb = sqListB->list, * pc = sqListC->list;
while (pa <= sqListA->list + sqListA->length - 1 && pb <= sqListB->list + sqListB->length - 1)
{
if (compare(*pa, *pb))
*pc++ = *pa++;
else
*pc++ = *pb++;
}
while (pa <= sqListA->list + sqListA->length - 1)
{
*pc++ = *pa++;
}
while (pb <= sqListB->list + sqListB->length - 1)
{
*pc++ = *pb++;
}
return OK;
}
// 按照非递减或者非递增的方式对顺序表进行冒泡排序
void BubbleSort_Sq(P_SqList& sqList, int (*compare)(ElemType, ElemType)) {
for (int round = 1; round < sqList->length; round++)
{
int hasExchanged = FALSE;
// 第round-1趟排序之后就已经有round-1个元素已经排好序了,所以只需要对前length-round+1个元素排序即可
for (int index = 0; index < sqList->length - round; index++)
{
if (!compare(sqList->list[index], sqList->list[index + 1]))
{
hasExchanged = TRUE;
ElemType tmp = sqList->list[index];
sqList->list[index] = sqList->list[index + 1];
sqList->list[index + 1] = tmp;
}
}
if (!hasExchanged)
{
break;
}
}
}
int main() {
P_SqList p_sqList = (P_SqList)new(SqList);
InitSqList(p_sqList);
InsertSqList(p_sqList, 1, 1);
InsertSqList(p_sqList, 1, 2);
cout << "当前顺序表中的元素为:";
PrintSqList(p_sqList);
ElemType elem_delete;
ElemType elem_get;
int order_delete = 1;
int order_getElem = 1;
GetSqListElem(p_sqList, order_getElem, elem_get);
cout << "删除第" << order_delete << "个元素前第" << order_getElem << "个元素为:" << elem_get << endl;
DeleteSqList(p_sqList, order_delete, elem_delete);
GetSqListElem(p_sqList, order_getElem, elem_get);
cout << "删除第" << order_delete << "个元素后第" << order_getElem << "个元素为:" << elem_get << endl;
cout << "删除的第" << order_delete << "个元素为:" << elem_delete << endl;
int order;
LocateSqListElem(p_sqList, 1, Equal, order);
cout << "值为1的元素在第" << order << "个位置上" << endl;
InsertSqList(p_sqList, 1, 4);
InsertSqList(p_sqList, 1, 5);
P_SqList p_sqList_B = (P_SqList)new(SqList);
InitSqList(p_sqList_B);
InsertSqList(p_sqList_B, 1, 4);
InsertSqList(p_sqList_B, 1, 1);
InsertSqList(p_sqList_B, 1, 6);
InsertSqList(p_sqList_B, 1, 8);
cout << "合并前的A表为:";
PrintSqList(p_sqList);
cout << "合并前的B表为:";
PrintSqList(p_sqList_B);
UnionSqList(p_sqList, p_sqList_B);
cout << "合并后的A表为:";
PrintSqList(p_sqList);
CopySqList(p_sqList, p_sqList_B);
cout << "拷贝后的B表为:";
PrintSqList(p_sqList_B);
ReverseSqList(p_sqList_B);
cout << "反转后的B表为:";
PrintSqList(p_sqList_B);
BubbleSort_Sq(p_sqList_B, LessEqual);
cout << "排序后的B表为:";
PrintSqList(p_sqList_B);
P_SqList p_sqList_C = (P_SqList)new(SqList);
InitSqList(p_sqList_C);
InsertSqList(p_sqList_C, 1, 3);
InsertSqList(p_sqList_C, 1, 1);
InsertSqList(p_sqList_C, 1, 7);
InsertSqList(p_sqList_C, 1, 2);
InsertSqList(p_sqList_C, 1, 9);
BubbleSort_Sq(p_sqList_C, LessEqual);
cout << "顺序表B:";
PrintSqList(p_sqList_B);
cout << "顺序表C:";
PrintSqList(p_sqList_C);
P_SqList p_sqList_D = (P_SqList)new(SqList);
InitSqList(p_sqList_D);
MergeSqList(p_sqList_B, p_sqList_C, p_sqList_D, LessEqual);
cout << "B和C融合后:";
PrintSqList(p_sqList_D);
delete p_sqList;
delete p_sqList_B;
return 0;
}