前言
定义一个枚举用于作为返回类型
typedef enum Result
{
RES_OK, // 函数运行成功
RES_BOOL_TRUE, // 布尔值true
RES_BOOL_FALSE, // 布尔值false
RES_CMP_EQUAL, // 比较结果为相等
RES_CMP_GREATER, // 比较结果为大于
RES_CMP_LESS, // 比较结果为小于
RES_BASE_ERROR, // 基础错误
// system err
RES_MALLOC_FAIL, // malloc失败
RES_PARA_ERROR, // 入参错误
RES_LIST_EMPTY_ERROR, // 表为空
RES_LIST_FULL_ERROR, // 表已满
RES_RANGE_ERROR // 范围错误
} Result;
元素类型相关
// 假设元素类型是 CElemType, 根据实际情况而定
// CElemType 类型的方法
// 比较两个元素的大小
Result ElementCompare(const CElemType* e1, const CElemType* e2);
// 元素赋值
Result ElementAssignment(CElemType* dest, const CElemType* src);
// 元素打印
Result PrintElement(const CElemType* e);
顺序表基础知识
顺序表基本定义
顺序表在物理结构上的表现就是一个大数组,其逻辑结构可以由物理结构来体现,所以无需用额外的代码来体现逻辑结构。
故而顺序表可以看作是一个大数组加上一些额外的信息,再加上一些方法。
定义一个顺序表结构
#define MAXSIZE 100 // 大数组的数目大小
typedef struct CSqList_t
{
CElemType data[MAXSIZE]; // 大数组
int length; // 额外的信息, 用于存储当前数组有效元素的数目
} CSqList;
顺序表的方法
获取某个位置的元素的值
/* 初始条件:顺序线性表L已存在,1≤pos≤ListLength(L) */
/* 操作结果:用e返回L中第pos个数据元素的值,注意pos是指位置,第1个位置的数组是从0开始 */
Result SeqListGetElem(const CSqList* list, int pos, CElemType* elem)
{
// 先对入参进行判断
if (NULL == list || NULL == elem)
{
printf("in SeqListGetElem:: in parameter err.\n");
return RES_PARA_ERROR;
}
// 判断顺序表是否为空
if (0 == list->length)
{
printf("in SeqListGetElem:: list is empty.\n");
return RES_LIST_EMPTY_ERROR;
}
// 判断位置的是否越界
if (pos < 1 || pos > list->length)
{
printf("in SeqListGetElem:: range of sqlist err.\n");
return RES_RANGE_ERROR;
}
// 使用ElementAssignment函数取出位置为pos的元素值赋予e
// 由于顺序表可以看作是一个大数组, 所以时间复杂度为 O(1)
return ElementAssignment(elem, &list->data[pos - 1]);
}
C语言版
CType.h
#ifndef _C_TYPES_H
#define _C_TYPES_H 1
#ifdef __cplusplus
extern "C" {
#endif
/*
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
*/
enum Result_t
{
RES_OK = 0,
RES_BOOL_TRUE,
RES_BOOL_FALSE,
RES_CMP_EQUAL,
RES_CMP_GREATER,
RES_CMP_LESS,
RES_BASE_ERROR,
RES_PARA_ERROR,
RES_LIST_EMPTY_ERROR,
RES_LIST_FULL_ERROR,
RES_RANGE_ERROR
};
typedef enum Result_t Result;
#define ELEM_IS_INT 0
#if !ELEM_IS_INT
struct CElemType_t
{
int index;
char message[64];
};
typedef struct CElemType_t CElemType;
#else
typedef int ElemType;
#endif
#define EXAMPLE_ELEM_ARRAY_LENGTH 100
extern CElemType EXAMPLE_ELEM_ARRAY[EXAMPLE_ELEM_ARRAY_LENGTH];
/**
* 元素比较:
* ret:
* e1 > e2: 1
* e1 == e2: 0
* e1 < e2: -1
* 入参错误: -2
**/
Result ElementCompare(const CElemType *e1, const CElemType *e2);
// 元素赋值
Result ElementAssignment(CElemType *dest, const CElemType *src);
// 元素打印
Result PrintElement(const CElemType *e);
#ifdef __cplusplus
}
#endif
#endif
CType.c
#include <stdio.h>
#include <string.h>
#include "CTypes.h"
CElemType EXAMPLE_ELEM_ARRAY[EXAMPLE_ELEM_ARRAY_LENGTH] = {
#if ELEM_IS_INT
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
#else
{0, "00"},
{1, "AA"},
{2, "BB"},
{3, "CC"},
{4, "DD"},
{5, "EE"},
{6, "FF"},
{7, "GG"},
{8, "HH"},
{9, "II"},
{10, "JJ"},
{11, "KK"},
{12, "LL"},
{13, "MM"},
{14, "NN"},
{15, "OO"},
{16, "PP"},
{17, "QQ"},
{18, "RR"},
{19, "SS"},
{20, "TT"}
#endif
};
// 元素赋值
Result ElementAssignment(CElemType *dest, const CElemType *src)
{
if (NULL == dest || NULL == src)
{
printf("in ElementAssignment:: in parameter err.\n");
return RES_PARA_ERROR;
}
#if ELEM_IS_INT
*dest = *src;
#else
dest->index = src->index;
strcpy(dest->message, src->message);
#endif
return RES_OK;
}
// 元素打印
Result PrintElement(const CElemType *e)
{
if (NULL == e)
{
printf("in %s:: in parameter err.\n", __func__);
return RES_PARA_ERROR;
}
#if ELEM_IS_INT
printf("%d ", *e);
#else
printf("%03d\t%s\n", e->index, e->message);
#endif
return RES_OK;
}
Result ElementCompare(const CElemType *e1, const CElemType *e2)
{
if (NULL == e1 || NULL == e2)
{
printf("in ElementAssignment:: in parameter err.\n");
return RES_PARA_ERROR;
}
#if ELEM_IS_INT
if (*e1 > *e2)
{
return RES_CMP_GREATER;
}
else if (*e1 < *e2)
{
return RES_CMP_LESS;
}
#else
if (e1->index > e2->index)
{
return RES_CMP_GREATER;
}
else if (e1->index < e2->index)
{
return RES_CMP_LESS;
}
else
{
int ret = strcmp(e1->message, e2->message);
if (ret > 0)
{
return RES_CMP_GREATER;
}
else if (ret < 0)
{
return RES_CMP_LESS;
}
}
#endif
return RES_CMP_EQUAL;
}
CSeqList.h
#ifndef _C_SeqList_H
#define _C_SeqList_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include "CTypes.h"
#define __TEST_C_SEQ_LIST__ 1 // 测试样例
// gcc ./CSeqList.c ./CTypes.c -I ./ -o c_seqlist_test -Wall
#define MAXSIZE 100
typedef struct CSqList_t
{
CElemType data[MAXSIZE];
int length;
} CSqList;
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 */
Result SeqListGetElem(const CSqList *list, int index, CElemType *elem);
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Result SeqListInsert(CSqList *list, int index, const CElemType *elem);
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Result SeqListDelete(CSqList *list, int index, CElemType *elem);
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Result SeqListIsEmpty(const CSqList *list);
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Result ClearSeqList(CSqList *list);
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int SeqListLength(const CSqList *list);
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:返回L中第1个与e满足相同关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int SeqListLocateElem(const CSqList *list, const CElemType* e);
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Result SeqListTraverse(const CSqList *list);
/*将所有的在线性表Lb中但不在La中的数据元素插入到La中*/
Result UnionSeqList(CSqList *La, const CSqList *Lb);
#ifdef __cplusplus
}
#endif
#endif
CSeqList.c
#include <stdio.h>
#include <string.h>
#include "CSeqList.h"
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 */
Result SeqListGetElem(const CSqList *list, int index, CElemType *elem)
{
if (NULL == list || NULL == elem)
{
printf("in SeqListGetElem:: in parameter err.\n");
return RES_PARA_ERROR;
}
if (0 == list->length)
{
printf("in SeqListGetElem:: list is empty.\n");
return RES_LIST_EMPTY_ERROR;
}
if (index < 1 || index > list->length)
{
printf("in SeqListGetElem:: range of sqlist err.\n");
return RES_RANGE_ERROR;
}
return ElementAssignment(elem, &list->data[index-1]);
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Result SeqListInsert(CSqList *list, int index, const CElemType *elem)
{
int i = 0;
Result ret;
if (NULL == list || NULL == elem)
{
printf("in SeqListInsert:: in parameter err.\n");
return RES_PARA_ERROR;
}
if (MAXSIZE == list->length)
{
printf("in SeqListInsert:: List full.\n");
return RES_LIST_FULL_ERROR;
}
if (index < 1 || index > list->length + 1)
{
printf("in SeqListInsert:: index is illegal, err.\n");
return RES_RANGE_ERROR;
}
for (i = list->length-1; i >= index-1; i--)
{
ret = ElementAssignment(&list->data[i+1], &list->data[i]);
if (ret != RES_OK)
{
printf("in SeqListInsert:: ElementAssignment() error.\n");
return ret;
}
}
ret = ElementAssignment(&list->data[index-1], elem);
if (ret != RES_OK)
{
printf("in SeqListInsert:: ElementAssignment() error.\n");
return ret;
}
list->length++;
return RES_OK;
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Result SeqListDelete(CSqList *list, int index, CElemType *elem)
{
int i = 0;
Result ret;
if (NULL == list)
{
printf("in SeqListDelete:: in parameter err.\n");
return RES_PARA_ERROR;
}
if (0 == list->length)
{
printf("in SeqListDelete:: list is empty.\n");
return RES_LIST_EMPTY_ERROR;
}
if (index < 1 || index > list->length)
{
printf("in SeqListDelete:: index is illegal.\n");
return RES_PARA_ERROR;
}
if (elem != NULL)
{
ret = ElementAssignment(elem, &list->data[index-1]);
if (ret != RES_OK)
{
printf("in SeqListDelete:: ElementAssignment() failed.\n");
return ret;
}
}
for (i = index; i < list->length; i++)
{
ret = ElementAssignment(&list->data[i-1], &list->data[i]);
if (ret != RES_OK)
{
printf("in SeqListDelete:: ElementAssignment() failed.\n");
return ret;
}
}
list->length--;
return RES_OK;
}
/* 创建顺序线性表 */
Result InitSeqList(CSqList* list)
{
if (NULL == list)
{
printf("in %s:: in parameter err.\n", __func__);
return RES_PARA_ERROR;
}
memset(list, 0, sizeof(CSqList));
list->length = 0;
return RES_OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Result SeqListIsEmpty(const CSqList *list)
{
if (NULL == list)
{
printf("in SeqListIsEmpty:: in parameter err.\n");
return RES_PARA_ERROR;
}
return ((list->length > 0) ? RES_BOOL_FALSE : RES_BOOL_TRUE);
}
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Result ClearSeqList(CSqList *list)
{
if (NULL == list)
{
printf("in %s:: in parameter err.\n", __func__);
return RES_PARA_ERROR;
}
list->length = 0;
return RES_OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int SeqListLength(const CSqList *list)
{
if (NULL == list)
{
printf("in %s:: in parameter err.\n", __func__);
return -1;
}
return list->length;
}
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int SeqListLocateElem(const CSqList *list, const CElemType* e)
{
int i = 0;
if (NULL == list || NULL == e)
{
printf("in %s:: in parameter err.\n", __func__);
return 0;
}
for (i = 0; i < list->length; i++)
{
if (ElementCompare(&list->data[i], e) == RES_CMP_EQUAL)
{
return i+1;
}
}
return 0;
}
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Result SeqListTraverse(const CSqList *list)
{
int i = 0;
Result ret;
if (NULL == list)
{
printf("in %s:: in parameter err.\n", __func__);
return RES_PARA_ERROR;
}
for (i = 0; i < list->length; i++)
{
ret = PrintElement(&list->data[i]);
if (ret != RES_OK)
{
printf("in SeqListTraverse:: PrintElement() failed.\n");
return ret;
}
}
printf("\n");
return RES_OK;
}
/*将所有的在线性表Lb中但不在La中的数据元素插入到La中*/
Result UnionSeqList(CSqList *La, const CSqList *Lb)
{
if (NULL == La || NULL == Lb)
{
printf("in %s:: in parameter err.\n", __func__);
return RES_PARA_ERROR;
}
int i = 0;
CElemType e;
Result ret;
int Lb_len = 0;
Lb_len = SeqListLength(Lb);
for (i = 1; i <= Lb_len; i++)
{
ret = SeqListGetElem(Lb, i, &e);
if (ret != RES_OK)
{
printf("in UnionSeqList:: SeqListGetElem() failed.\n");
return ret;
}
if (SeqListLocateElem(La, &e) != 0)
{
continue;
}
ret = SeqListInsert(La, SeqListLength(La)+1, &e);
if (ret != RES_OK)
{
printf("in UnionSeqList:: SeqListInsert() failed.\n");
return ret;
}
}
return RES_OK;
}
#if __TEST_C_SEQ_LIST__
#include <stdlib.h>
void JudgeRes(Result res, int line)
{
if (res >= RES_BASE_ERROR)
{
printf("exit() in [%d].\n", line);
exit(1);
}
}
int main()
{
int i, j;
CSqList L;
CSqList Lb;
CElemType e;
Result ret;
ret = InitSeqList(&L);
JudgeRes(ret, __LINE__);
printf("初始化L后: SeqListLength(&L) = [%d].\n", SeqListLength(&L));
for (i = 1; i <= 5; i++)
{
ret = SeqListInsert(&L, 1, &EXAMPLE_ELEM_ARRAY[i]);
JudgeRes(ret, __LINE__);
}
printf("在L的表头依次插入 EXAMPLE_ELEM_ARRAY[1]~EXAMPLE_ELEM_ARRAY[5] 后: L.data = \n");
ret = SeqListTraverse(&L);
JudgeRes(ret, __LINE__);
printf("SeqListLength(&L) = [%d].\n", SeqListLength(&L));
ret = SeqListIsEmpty(&L);
JudgeRes(ret, __LINE__);
if (RES_BOOL_TRUE == ret)
{
printf("L is empty.\n");
}
else if (RES_BOOL_FALSE == ret)
{
printf("L is not empty.\n");
}
ret = ClearSeqList(&L);
JudgeRes(ret, __LINE__);
printf("ClearSeqList()后: SeqListLength(&L) = [%d].\n", SeqListLength(&L));
ret = SeqListIsEmpty(&L);
JudgeRes(ret, __LINE__);
if (RES_BOOL_TRUE == ret)
{
printf("L is empty.\n");
}
else if (RES_BOOL_FALSE == ret)
{
printf("L is not empty.\n");
}
for (i = 1; i <= 10; i++)
{
ret = SeqListInsert(&L, SeqListLength(&L)+1, &EXAMPLE_ELEM_ARRAY[i]);
JudgeRes(ret, __LINE__);
}
printf("在L的表尾依次插入 EXAMPLE_ELEM_ARRAY[1]~EXAMPLE_ELEM_ARRAY[10] 后: L.data = \n");
ret = SeqListTraverse(&L);
JudgeRes(ret, __LINE__);
printf("SeqListLength(&L) = [%d].\n", SeqListLength(&L));
ret = SeqListInsert(&L, 1, &EXAMPLE_ELEM_ARRAY[0]);
JudgeRes(ret, __LINE__);
printf("在L的表头插入 EXAMPLE_ELEM_ARRAY[0] 后: L.data = \n");
ret = SeqListTraverse(&L);
JudgeRes(ret, __LINE__);
printf("SeqListLength(&L) = [%d].\n", SeqListLength(&L));
ret = SeqListGetElem(&L, 5, &e);
JudgeRes(ret, __LINE__);
printf("第5个元素的值为:\n");
PrintElement(&e);
printf("\n");
for (j = 3; j <= 4; j++)
{
i = SeqListLocateElem(&L, &EXAMPLE_ELEM_ARRAY[j]);
if (i != 0)
{
printf("第[%d]个元素的值为:\n", i);
PrintElement(&EXAMPLE_ELEM_ARRAY[j]);
printf("\n");
}
else
{
printf("没有值为:\n");
PrintElement(&EXAMPLE_ELEM_ARRAY[j]);
printf("\n的元素.\n");
}
}
i = SeqListLength(&L);
for (j = i+1; j>=i; j--)
{
ret = SeqListDelete(&L, j, &e); /* 删除第j个数据 */
if (ret != RES_OK)
{
printf("删除第[%d]个数据失败\n",j);
}
else
{
printf("删除第%d个的元素值为:\n", j);
PrintElement(&e);
printf("\n");
}
}
printf("依次输出L的元素:\n");
ret = SeqListTraverse(&L);
JudgeRes(ret, __LINE__);
j = 5;
ret = SeqListDelete(&L, j, &e); /* 删除第j个数据 */
if (ret != RES_OK)
{
printf("删除第[%d]个数据失败\n", j);
}
else
{
printf("删除第%d个的元素值为:\n", j);
PrintElement(&e);
printf("\n");
}
printf("依次输出L的元素:\n");
ret = SeqListTraverse(&L);
JudgeRes(ret, __LINE__);
ret = InitSeqList(&Lb);
JudgeRes(ret, __LINE__);
for (i = 6; i <= 15; i++)
{
ret = SeqListInsert(&Lb, 1, &EXAMPLE_ELEM_ARRAY[i]);
JudgeRes(ret, __LINE__);
}
ret = UnionSeqList(&L, &Lb);
JudgeRes(ret, __LINE__);
printf("依次输出L的元素:\n");
ret = SeqListTraverse(&L);
JudgeRes(ret, __LINE__);
return 0;
}
#endif
C++ 版本
Type.hpp
#ifndef _TYPE_H
#define _TYPE_H 1
#include <cstring>
#include <iostream>
enum class Result : unsigned
{
RES_OK = 0,
RES_BASE_ERROR,
RES_INIT_FAIL,
RES_PARA_ERROR,
RES_LIST_EMPTY_ERROR,
RES_LIST_FULL_ERROR,
RES_RANGE_ERROR,
RES_MALLOC_FAIL
};
class ElemType
{
private:
int m_index;
char m_message[64];
public:
friend std::ostream& operator<<(std::ostream& stream, const ElemType& e);
public:
ElemType() noexcept
: m_index(0)
{
std::memset(m_message, 0, sizeof(m_message));
}
ElemType(const ElemType& elem) noexcept
: m_index(elem.m_index)
{
std::strcpy(m_message, elem.m_message);
}
ElemType(int index, const char *message) noexcept
: m_index(index)
{
std::strncpy(m_message, message, sizeof(m_message));
}
~ElemType() = default;
bool operator<(const ElemType& other) noexcept
{
if (this->m_index < other.m_index)
{
return true;
}
if (this->m_index == other.m_index && std::strcmp(this->m_message, other.m_message) < 0)
{
return true;
}
return false;
}
bool operator==(const ElemType& other) noexcept
{
if (this->m_index == other.m_index && std::strcmp(this->m_message, other.m_message) == 0)
{
return true;
}
return false;
}
bool operator>(const ElemType& other) noexcept
{
if (*this < other)
{
return false;
}
else if (*this == other)
{
return false;
}
return true;
}
ElemType& operator=(const ElemType& other) noexcept
{
if (this != &other)
{
m_index = other.m_index;
std::memset(m_message, 0, sizeof(m_message));
std::strcpy(m_message, other.m_message);
}
return *this;
}
};
std::ostream& operator<<(std::ostream& stream, const ElemType& e)
{
stream << e.m_index << '\t' << e.m_message << '\n';
return stream;
}
#endif
SeqList.cpp
#ifndef _SEQLIST_H
#define _SEQLIST_H 1
#include <string>
#include <iostream>
#include <exception>
#include <functional>
#include "Type.hpp"
#define __TEST_SEQLIST__ 1
template <typename T> class SeqList
{
private:
T* m_data;
int m_length;
const int m_max_nums;
public:
SeqList(int max_nums, Result& res) noexcept
: m_data(nullptr), m_length(0), m_max_nums(max_nums)
{
res = Result::RES_OK;
try
{
m_data = new T[m_max_nums];
}
catch (const std::exception& e)
{
std::cout << "in SeqList:: new failed, exception = " << e.what() << std::endl;
res = Result::RES_INIT_FAIL;
}
}
SeqList(const SeqList& L)
: m_data(nullptr), m_length(0), m_max_nums(L.m_max_nums)
{
Result res;
std::string exception_message;
try
{
m_data = new T[m_max_nums];
for (int i = 0; i < L.length(); i++)
{
res = this->insert(i, L[i]);
if (res != Result::RES_OK)
{
exception_message = std::string("in SeqList:: this->insert() failed.");
break;
}
}
}
catch (const std::exception& e)
{
res = Result::RES_INIT_FAIL;
exception_message = std::string("in SeqList:: new failed, exception = ") + std::string(e.what());
}
if (res != Result::RES_OK)
{
throw std::out_of_range(exception_message);
}
}
SeqList& operator=(const SeqList& L)
{
if (this == &L)
{
return *this;
}
if (m_data != nullptr)
{
delete[] m_data;
m_data = nullptr;
}
m_length = 0;
{
int& ref_m_max_nums = const_cast<int&>(this->m_max_nums);
ref_m_max_nums = L.m_max_nums;
}
Result res;
std::string exception_message;
try
{
m_data = new T[m_max_nums];
for (int i = 0; i < L.length(); i++)
{
res = this->insert(i, L[i]);
if (res != Result::RES_OK)
{
exception_message = std::string("in SeqList:: this->insert() failed.");
break;
}
}
}
catch (const std::exception& e)
{
res = Result::RES_INIT_FAIL;
exception_message = std::string("in SeqList:: new failed, exception = ") + std::string(e.what());
}
if (res != Result::RES_OK)
{
throw std::out_of_range(exception_message);
}
}
SeqList(SeqList&& L) noexcept
: m_data(L.m_data), m_length(L.m_length), m_max_nums(L.m_max_nums)
{
L.m_data = nullptr;
L.m_length = 0;
}
SeqList& operator=(SeqList&& L) noexcept
{
if (this == &L)
{
return *this;
}
if (m_data != nullptr)
{
delete[] m_data;
m_data = nullptr;
}
m_data = L.m_data;
L.m_data = nullptr;
m_length = L.m_length;
L.m_length = 0;
{
int& ref_m_max_nums = const_cast<int&>(this->m_max_nums);
ref_m_max_nums = L.m_max_nums;
}
}
SeqList(const SeqList& L, Result& res) noexcept
: m_data(nullptr), m_length(0), m_max_nums(L.m_max_nums)
{
res = Result::RES_OK;
try
{
m_data = new T[m_max_nums];
for (int i = 0; i < L.length(); i++)
{
res = this->insert(i, L[i]);
if (res != Result::RES_OK)
{
std::cout << "in SeqList:: this->insert() failed.\n";
break;
}
}
}
catch (const std::exception& e)
{
std::cout << "in SeqList:: new failed, exception = " << e.what() << std::endl;
res = Result::RES_INIT_FAIL;
}
}
~SeqList() noexcept
{
if (m_data != nullptr)
{
delete[] m_data;
m_data = nullptr;
}
m_length = 0;
}
T& operator[] (int index)
{
const char *exception_message = nullptr;
if (nullptr == m_data)
{
exception_message = "in SeqList::operator[]:: list not init()";
}
else if (0 == m_length)
{
exception_message = "in SeqList::operator[]:: list empty";
}
else if (index < 1 || index > m_length)
{
exception_message = "in SeqList::operator[]:: index illegal";
}
if (exception_message != nullptr)
{
std::cout << exception_message << std::endl;
throw std::out_of_range(exception_message);
}
return m_data[index-1];
}
const T& operator[] (int index) const
{
const char *exception_message = nullptr;
if (nullptr == m_data)
{
exception_message = "in SeqList::operator[]:: list not init()";
}
else if (0 == m_length)
{
exception_message = "in SeqList::operator[]:: list empty";
}
else if (index < 1 || index > m_length)
{
exception_message = "in SeqList::operator[]:: index illegal";
}
if (exception_message != nullptr)
{
std::cout << exception_message << std::endl;
throw std::out_of_range(exception_message);
}
return m_data[index-1];
}
Result insert(int index, const T &e) noexcept
{
if (nullptr == m_data)
{
std::cout << "in SeqList::insert:: list is not init.\n";
return Result::RES_LIST_EMPTY_ERROR;
}
if (m_max_nums == m_length)
{
std::cout << "in SeqList::insert:: list full.\n";
return Result::RES_LIST_FULL_ERROR;
}
if (index < 1 || index > m_length + 1)
{
std::cout << "in SeqList::insert:: index illegal.\n";
return Result::RES_PARA_ERROR;
}
for (int i = m_length-1; i >= index-1; i--)
{
m_data[i+1] = std::move(m_data[i]);
}
m_data[index-1] = e;
m_length++;
return Result::RES_OK;
}
Result del(int index, T *del_elem = nullptr) noexcept
{
if (nullptr == m_data)
{
std::cout << "in SeqList::del:: list is not init.\n";
return Result::RES_LIST_EMPTY_ERROR;
}
if (0 == m_length)
{
std::cout << "in SeqList::del:: list is empty.\n";
return Result::RES_LIST_EMPTY_ERROR;
}
if (index < 1 || index > m_length)
{
std::cout << "in SeqList::del:: index illegal.\n";
return Result::RES_PARA_ERROR;
}
if (del_elem != nullptr)
{
*del_elem = std::move(m_data[index-1]);
}
for (int i = index; i < m_length; i++)
{
m_data[i-1] = std::move(m_data[i]);
}
m_length--;
return Result::RES_OK;
}
bool is_empty() const noexcept
{
return (m_length == 0 ? true : false);
}
Result clear() noexcept
{
if (nullptr == m_data)
{
std::cout << "in SeqList::clear:: list is not init.\n";
return Result::RES_LIST_EMPTY_ERROR;
}
m_length = 0;
return Result::RES_OK;
}
int length() const noexcept
{
return m_length;
}
/**
* 初始条件:顺序线性表L已存在
* 操作结果:返回L中第1个与e满足关系的数据元素的位序。
* 若这样的数据元素不存在,则返回值为0
**/
int locate_elem(const T& e)
{
if (nullptr == m_data)
{
std::cout << "in SeqList::locate_elem:: list is not init.\n";
return 0;
}
for (int i = 0; i < m_length; i++)
{
if (m_data[i] == e)
{
return i+1;
}
}
return 0;
}
void traverse(std::ostream& out_stream = std::cout) noexcept
{
for (int i = 0; i < m_length; i++)
{
out_stream << m_data[i];
}
out_stream << '\n';
}
SeqList& operator+=(const SeqList& other_list)
{
const char *exception_message = nullptr;
if (nullptr == m_data || nullptr == other_list.m_data)
{
exception_message = "in SeqList::locate_elem:: list is not init.";
std::cout << exception_message << std::endl;
throw std::out_of_range(exception_message);
}
T e;
for (int i = 1; i <= other_list.length(); i++)
{
e = other_list[i];
if (this->locate_elem(e) != 0)
{
continue;
}
if (this->insert(this->length()+1, e) != Result::RES_OK)
{
exception_message = "in SeqList::operator+=:: this->insert() failed.";
std::cout << exception_message << std::endl;
throw std::out_of_range(exception_message);
}
}
return *this;;
}
};
#endif
cplusplus_test.cpp
#include <iostream>
#include "SeqList.hpp"
// g++ -std=c++23 -Wall cplusplus_test.cpp -I ./ -o cplusplus_test
static void JudgeRes(const Result& res, int line)
{
if (res >= Result::RES_BASE_ERROR)
{
printf("exit() in [%d].\n", line);
exit(1);
}
}
ElemType EXAMPLE_ELEM_ARRAY[] = {
ElemType(0, "00"),
ElemType(1, "AA"),
ElemType(2, "BB"),
ElemType(3, "CC"),
ElemType(4, "DD"),
ElemType(5, "EE"),
ElemType(6, "FF"),
ElemType(7, "GG"),
ElemType(8, "HH"),
ElemType(9, "II"),
ElemType(10, "JJ"),
ElemType(11, "KK"),
ElemType(12, "LL"),
ElemType(13, "MM"),
ElemType(14, "NN"),
ElemType(15, "OO"),
ElemType(16, "PP"),
ElemType(17, "QQ"),
ElemType(18, "RR"),
ElemType(19, "SS"),
ElemType(20, "TT")
};
int main()
{
int i = 0;
Result ret;
ElemType elem;
#if __TEST_SEQLIST__
SeqList<ElemType> L(100, ret);
JudgeRes(ret, __LINE__);
SeqList<ElemType> Lb(100, ret);
JudgeRes(ret, __LINE__);
std::cout << "初始化L后: L.length() = " << L.length() << std::endl;
for (i = 1; i <= 5; i++)
{
ret = L.insert(1, EXAMPLE_ELEM_ARRAY[i]);
JudgeRes(ret, __LINE__);
}
std::cout << "在L的表头依次插入 EXAMPLE_ELEM_ARRAY[1]~EXAMPLE_ELEM_ARRAY[5] 后: L.data = \n";
L.traverse();
std::cout << "L.length() = " << L.length() << std::endl;
if (true == L.is_empty())
{
std::cout << "L is empty.\n";
}
else
{
std::cout << "L is not empty.\n";
}
ret = L.clear();
JudgeRes(ret, __LINE__);
std::cout << "L.clear()后: L.length() = " << L.length() << std::endl;
if (true == L.is_empty())
{
std::cout << "L is empty.\n";
}
else
{
std::cout << "L is not empty.\n";
}
for (i = 1; i <= 10; i++)
{
ret = L.insert(L.length()+1, EXAMPLE_ELEM_ARRAY[i]);
JudgeRes(ret, __LINE__);
}
std::cout << "在L的表尾依次插入 EXAMPLE_ELEM_ARRAY[1]~EXAMPLE_ELEM_ARRAY[10] 后: L.data = \n";
L.traverse();
std::cout << "L.length() = " << L.length() << std::endl;
ret = L.insert(1, EXAMPLE_ELEM_ARRAY[0]);
JudgeRes(ret, __LINE__);
std::cout << "在L的表头插入 EXAMPLE_ELEM_ARRAY[0] 后: L.data = \n";
L.traverse();
JudgeRes(ret, __LINE__);
std::cout << "L.length() = " << L.length() << std::endl;
try {
elem = L[5];
}
catch (const std::exception& e)
{
std::cout << "Get Elem failed.\n";
exit(-1);
}
std::cout << "第5个元素的值为:\n";
std::cout << elem << std::endl;
for (int j = 3; j <= 4; j++)
{
i = L.locate_elem(EXAMPLE_ELEM_ARRAY[j]);
if (i != 0)
{
std::cout << "第[" << i << "]个元素的值为:\n";
std::cout << EXAMPLE_ELEM_ARRAY[j] << std::endl;
}
else
{
std::cout << "没有值为:\n";
std::cout << EXAMPLE_ELEM_ARRAY[j] << "\n的元素.\n";
}
}
i = L.length();
for (int j = i+1; j >= i; j--)
{
ret = L.del(j, &elem);
if (ret != Result::RES_OK)
{
std::cout << "删除第[" << j << "]个数据失败\n";
}
else
{
std::cout << "删除第[" << j << "]个的元素值为:\n" << elem << std::endl;
}
}
std::cout << "依次输出L的元素:\n";
L.traverse();
i = 5;
ret = L.del(i, &elem);
if (ret != Result::RES_OK)
{
std::cout << "删除第[" << i << "]个数据失败\n";
}
else
{
std::cout << "删除第[" << i << "]个的元素值为:\n" << elem << std::endl;
}
std::cout << "依次输出L的元素:\n";
L.traverse();
for (i = 6; i <= 15; i++)
{
ret = Lb.insert(1, EXAMPLE_ELEM_ARRAY[i]);
JudgeRes(ret, __LINE__);
}
L += Lb;
std::cout << "依次输出L的元素:\n";
L.traverse();
#endif
return 0;
}