[C/C++] 数据结构-顺序表代码

前言

定义一个枚举用于作为返回类型

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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值