(三)第 2 章 线性表(线性表的动态分配顺序存储)

1. 背景说明

线性表(linear Iist)是最常用且最简单的一种数据结构。简言之,一个线性表是 n 个数据元素的有限序列。

至于每个数据元素的具体含义,在不同的情况下各不相同,它可以是一个数或一个符号,也可以是一页书,甚至其他更复杂的信息。

2. 示例代码

1) errorRecord.h

// 记录错误宏定义头文件

#ifndef ERROR_RECORD_H
#define ERROR_RECORD_H

#include <stdio.h>
#include <string.h>
#include <stdint.h>

// Extracts the file name from the file path
#define FILE_NAME(X) strrchr(X, '\\') ? strrchr(X, '\\') + 1 : X

// Define DEBUG macro for enabling debug mode
#define DEBUG

// Print error message
#ifdef DEBUG
#define ERR_RECORD(ERR_CODE, ...) do { \
    printf(ANSI_COLOR_BRIGHT_CYAN \
        "\n\nFile: %-25s Func: %-20s Line: %-10d ErrorCode: %-8d ErrorInfo: ", \
        FILE_NAME(__FILE__), __func__, __LINE__, (ERR_CODE)); \
    printf(""__VA_ARGS__); \
    printf("\n" ANSI_COLOR_RESET); \
    PrintErrorCodeInfo(ERR_CODE); \
} while (0)
#else
#define ERR_RECORD(ERR_CODE, FORMAT, ...)
#endif

// Function result status codes
enum StatusCode {
	RET_OK = 0,                 // Operation successful
	ERR_NULL_PTR = 1,           // Null pointer error
	ERR_MEMORY_ALLOCATE = 2,    // Memory allocation error
	ERR_EMPTY_STACK = 3,        // Empty stack error
	ERR_FULL_STACK = 4,			// Full stack error
	ERR_EMPTY_QUEUE = 5,        // Empty queue error
	ERR_FULL_QUEUE = 6,         // Full queue error
	ERR_PARA_ILLEGAL = 7,       // Parameter illegal error
	ERR_OPEN_FILE = 8,          // File open error
	ERR_NOT_EXIST = 9,          // Not exist error
};

enum BoolCode {
	TRUE = 1,
	FALSE = 0
};

typedef uint32_t Status;
typedef uint8_t Boolean;

// ANSI 转义码定义
#define ANSI_COLOR_BRIGHT_RED     "\x1b[91m"
#define ANSI_COLOR_BRIGHT_YELLOW  "\x1b[93m"
#define ANSI_COLOR_BRIGHT_CYAN    "\x1b[96m"
#define ANSI_COLOR_RESET          "\x1b[0m"

// Function to print error code information with bright colors
static void PrintErrorCodeInfo(int errorCode)
{
	switch (errorCode) {
		case ERR_NULL_PTR:
			printf(ANSI_COLOR_BRIGHT_RED "Null Pointer Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_MEMORY_ALLOCATE:
			printf(ANSI_COLOR_BRIGHT_RED "Memory Allocation Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_EMPTY_STACK:
			printf(ANSI_COLOR_BRIGHT_RED "Empty Stack Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_FULL_STACK:
			printf(ANSI_COLOR_BRIGHT_RED "Full Stack Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_EMPTY_QUEUE:
			printf(ANSI_COLOR_BRIGHT_RED "Empty Queue Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_FULL_QUEUE:
			printf(ANSI_COLOR_BRIGHT_RED "Full Queue Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_PARA_ILLEGAL:
			printf(ANSI_COLOR_BRIGHT_RED "Illegal Parameter Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_OPEN_FILE:
			printf(ANSI_COLOR_BRIGHT_RED "File Open Error\n\n" ANSI_COLOR_RESET);
			break;

		case ERR_NOT_EXIST:
			printf(ANSI_COLOR_BRIGHT_RED "Not Exist Error\n\n" ANSI_COLOR_RESET);
			break;

		default:
			printf(ANSI_COLOR_BRIGHT_YELLOW "Unknown Error Code: %d\n\n" ANSI_COLOR_RESET,
				errorCode);
			break;
	}
}

#endif // !ERROR_RECORD_H

2) dynSqList.h

// 线性表的动态分配顺序存储结构头文件

#ifndef DYN_SQLIST_H
#define DYN_SQLIST_H

#include "errorRecord.h"

#define LIST_INIT_SIZE 10 		// 线性表存储空间的初始分配量
#define LISTINCREMENT 2 		// 线性表存储空间的分配增量

typedef int ElemType;

typedef struct {
	ElemType *elem;				// 存储空间基址
	int length;					// 当前长度
	int listSize;				// 当前分配的存储容量(以 sizeof(ElemType) 为单位)
} SqList;

typedef void(*Visit)(ElemType *);
typedef int(*Compare)(ElemType, ElemType);

Status InitList(SqList *list);

Status DestroyList(SqList *list);

Status ClearList(SqList *list);

Status ListEmpty(const SqList *list, Boolean *isEmpty);

Status ListLength(const SqList *list, int *num);

Status GetElem(const SqList *list, int i, ElemType *e);

Status LocateElem(const SqList *list, ElemType e,
	Boolean(*compare)(ElemType, ElemType), int *pos);

Status PriorElem(const SqList *list, ElemType cur_e, ElemType *pre_e);

Status NextElem(const SqList *list, ElemType cur_e, ElemType *next_e);

Status ListInsert(int i, ElemType e, SqList *list);

Status ListDelete(int i, SqList *list, ElemType *e);

Status ListTraverse(const SqList *list, Visit visit);

Status InsertAscend(ElemType e, Compare compare, SqList *list);

Status InsertDescend(ElemType e, Compare compare, SqList *list);

Status HeadInsert(ElemType e, SqList *list);

Status EndInsert(ElemType e, SqList *list);

Status DeleteFirst(SqList *list, ElemType *e);

Status DeleteTail(SqList *list, ElemType *e);

Status DeleteElem(ElemType e, Boolean(*compare)(ElemType, ElemType),
	SqList *list);

Status RePlaceElem(const SqList *list, int i, ElemType e);

#endif // !DYN_SQLIST_H

3) dynSqList.c

// 线性表的动态分配顺序存储结构实现源文件

#include "dynSqList.h"
#include <stdlib.h>

/*
	算法 2.3
	前置条件:list 非空
	操作结果:构造一个空的顺序线性表
*/
Status InitList(SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	list->elem = (ElemType *)malloc(sizeof(ElemType) * LIST_INIT_SIZE);
	if (!(list->elem)) {
		ERR_RECORD(ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	list->length = 0;
	list->listSize = LIST_INIT_SIZE;

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:销毁顺序线性表 *list
*/
Status DestroyList(SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	free(list->elem);
	list->elem = NULL;
	list->length = 0;
	list->listSize = 0;

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:将 *list 重置为空表
*/
Status ClearList(SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	list->length = 0;

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:若 *list 为空表,则用 *isEmpty 返回 TRUE,否则用 *isEmpty 返回 FALSE
*/
Status ListEmpty(const SqList *list, Boolean *isEmpty)
{
	if (!list || !isEmpty) {
		ERR_RECORD(ERR_NULL_PTR, "list = %p, isEmpty = %p", list, isEmpty);
		return ERR_NULL_PTR;
	}

	*isEmpty = (list->length == 0) ? TRUE : FALSE;

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:用 *num 返回 *list 中数据元素个数
*/
Status ListLength(const SqList *list, int *num)
{
	if (!list || !num) {
		ERR_RECORD(ERR_NULL_PTR, "list = %p, num = %p", list, num);
		return ERR_NULL_PTR;
	}

	*num = list->length;

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在,1 ≤ i ≤ listLength
	操作结果:用 *e 返回 *list 中第 i 个数据元素的值
*/
Status GetElem(const SqList *list, int i, ElemType *e)
{
	if (!list || !e) {
		ERR_RECORD(ERR_NULL_PTR, "list = %p, e = %p", list, e);
		return ERR_NULL_PTR;
	}

	if ((i < 1) || (i > list->length)) {
		ERR_RECORD(ERR_NOT_EXIST, "i = %d, listLength = %d", i, list->length);
		return ERR_NOT_EXIST;
	}

	*e = *(list->elem + i - 1);

	return RET_OK;
}

/*
	算法 2.6
	前置条件:顺序线性表 *list 已存在,compare() 是数据元素判定函数(满足为 1,否则为 0)
	操作结果:用 *pos 返回 *list 中第 1 个与 e 满足关系 compare() 的数据元素的位序,
			  若这样的数据元素不存在,则用 *pos 返回值为 0
*/
Status LocateElem(const SqList *list, ElemType e,
	Boolean(*compare)(ElemType, ElemType), int *pos)
{
	if (!compare || !list || !pos) {
		ERR_RECORD(ERR_NULL_PTR, "compare = %p, list = %p, pos = %p",
			compare, list, pos);
		return ERR_NULL_PTR;
	}

	ElemType *p = list->elem;
	int i = 1;

	/* 第 1 个判断条件确保指针 p 不为空 */
	while ((i <= list->length) && (!compare(*p++, e))) {
		++i;
	}

	*pos = (i <= list->length) ? i : 0;
	if (!*pos) {
		ERR_RECORD(ERR_NOT_EXIST, "i = %d, listLength = %d", i, list->length);
		return ERR_NOT_EXIST;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:若 cur_e 是 *list 的数据元素,且不是第一个,则用 *pre_e 返回它的前驱
*/
Status PriorElem(const SqList *list, ElemType cur_e, ElemType *pre_e)
{
	if (!list || !pre_e) {
		ERR_RECORD(ERR_NULL_PTR, "list = %p, pre_e = %p", list, pre_e);
		return ERR_NULL_PTR;
	}

	int i = 2;
	ElemType *p = list->elem + 1;

	/* 确保了不会非法解引用指针 */
	while ((i++ <= list->length) && (*p++ != cur_e)) {
		continue;
	}

	/* 考虑最后一个可能是 cur_e */
	if (i > list->length + 1) {
		ERR_RECORD(ERR_NOT_EXIST, "i = %d, listLength = %d", i, list->length);
		return ERR_NOT_EXIST;
	}

	*pre_e = *(p - 2);

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:若 cur_e 是 *list 的数据元素,且不是最后一个,则用 *next_e 返回它的后继
*/
Status NextElem(const SqList *list, ElemType cur_e, ElemType *next_e)
{
	if (!list || !next_e) {
		ERR_RECORD(ERR_NULL_PTR, "list = %p, next_e = %p", list, next_e);
		return ERR_NULL_PTR;
	}

	int i = 1;
	ElemType *p = list->elem;

	/* 确保了不会非法解引用指针 */
	while (i < (list->length) && (*p != cur_e)) {
		++i;
		++p;
	}

	if (i == list->length) {
		ERR_RECORD(ERR_NOT_EXIST, "i = %d, listLength = %d", i, list->length);
		return ERR_NOT_EXIST;
	}

	*next_e = *(++p);

	return RET_OK;
}

/*
	算法 2.4
	前置条件:顺序线性表 *list 已存在,1 ≤ i ≤ listLength + 1
	操作结果:在 *list 中第 i 个位置之前插入新的数据元素 e,*list 的长度加 1
*/
Status ListInsert(int i, ElemType e, SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	if ((i < 1) || (i > list->length + 1)) {
		ERR_RECORD(ERR_PARA_ILLEGAL, "i = %d", i);
		return ERR_PARA_ILLEGAL;
	}

	if (list->length == list->listSize) {
		ElemType *newBase = (ElemType *)realloc(list->elem, sizeof(ElemType) *
			(unsigned long long)(list->listSize + LISTINCREMENT));
		if (!newBase) {
			ERR_RECORD(ERR_MEMORY_ALLOCATE);
			return ERR_MEMORY_ALLOCATE;
		}

		list->elem = newBase;
		list->listSize += LISTINCREMENT;
	}

	ElemType *q = list->elem + i - 1;

	for (ElemType *p = list->elem + list->length - 1; p >= q; --p) {
		*(p + 1) = *p;
	}

	*q = e;
	++(list->length);

	return RET_OK;
}

/*
	算法 2.5
	前置条件:顺序线性表 *list 已存在,1 ≤ i ≤ listLength
	操作结果:删除 *list 的第 i 个数据元素,并用 *e 返回其值,*list 的长度减 1
*/
Status ListDelete(int i, SqList *list, ElemType *e)
{
	if (!e || !list) {
		ERR_RECORD(ERR_NULL_PTR, "e = %p, list = %p", e, list);
		return ERR_NULL_PTR;
	}

	if ((i < 1) || (i > list->length)) {
		ERR_RECORD(ERR_NOT_EXIST, "i = %d, listLength = %d", i, list->length);
		return ERR_NOT_EXIST;
	}

	ElemType *p = list->elem + i - 1;
	*e = *p;
	ElemType *q = list->elem + list->length - 1;

	for (++p; p <= q; ++p) {
		*(p - 1) = *p;
	}

	--(list->length);

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:依次对 *list 的每个数据元素调用函数 visit()。一旦 visit() 失败,
			  则操作失败, visit() 的形参加 '*',表明可通过调用 visit() 改变元素的值
*/
Status ListTraverse(const SqList *list, Visit visit)
{
	if (!list || !visit) {
		ERR_RECORD(ERR_NULL_PTR, "list = %p, visit = %p", list, visit);
		return ERR_NULL_PTR;
	}

	ElemType *p = list->elem;

	for (int i = 0; i < list->length; ++i) {
		visit(p++);
	}

	return RET_OK;
}

static int GetInsertPos(const SqList *list, ElemType e, Boolean isAscend,
	int(*compare)(ElemType, ElemType))
{
	int i = 0;

	if (isAscend == TRUE) {
		while ((i < list->length) && (compare(e, *(list->elem + i)) > 0)) {
			++i;
		}

		return (i + 1);
	}

	while ((i < list->length) && (compare(e, *(list->elem + i)) < 0)) {
		++i;
	}

	return (i + 1);
}

/*
	前置条件:按非降序排列的顺序线性表 *list 已存在
	操作结果:在 *list 中按非降序插入新的数据元素 e,*list 的长度加 1
*/
Status InsertAscend(ElemType e, Compare compare, SqList *list)
{
	if (!compare || !list) {
		ERR_RECORD(ERR_NULL_PTR, "compare = %p, list = %p", compare, list);
		return ERR_NULL_PTR;
	}

	Status ret = ListInsert(GetInsertPos(list, e, TRUE, compare), e, list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:按非降序排列的顺序线性表 *list 已存在
	操作结果:在 *list 中按非升序插入新的数据元素 e,*list 的长度加 1
*/
Status InsertDescend(ElemType e, Compare compare, SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	Status ret = ListInsert(GetInsertPos(list, e, FALSE, compare), e, list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:在 *list 的头部插入新的数据元素 e,*list 的长度加 1
*/
Status HeadInsert(ElemType e, SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	Status ret = ListInsert(1, e, list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:在 *list 的尾部插入新的数据元素 e,*list 的长度加 1
*/
Status EndInsert(ElemType e, SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	Status ret = ListInsert(list->length + 1, e, list);
	if (ret != RET_OK) {
		ERR_RECORD(ret, "list->length = %d", list->length);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在,且有不少于 1 个元素
	操作结果:删除 *list 的第一个数据元素,并由 *e 返回其值,*list 的长度减 1
*/
Status DeleteFirst(SqList *list, ElemType *e)
{
	if (!e || !list) {
		ERR_RECORD(ERR_NULL_PTR, "e  = %p, list = %p", e, list);
		return ERR_NULL_PTR;
	}

	Status ret = ListDelete(1, list, e);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在,且有不少于 1 个元素
	操作结果:删除 *list 的最后一个数据元素,并用 e 返回其值,*list 的长度减 1
*/
Status DeleteTail(SqList *list, ElemType *e)
{
	if (!e || !list) {
		ERR_RECORD(ERR_NULL_PTR, "e  = %p, list = %p", e, list);
		return ERR_NULL_PTR;
	}

	Status ret = ListDelete(list->length, list, e);
	if (ret != RET_OK) {
		ERR_RECORD(ret, "list->length = %d", list->length);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:删除表中值为 e 的元素
*/
Status DeleteElem(ElemType e, Boolean(*compare)(ElemType, ElemType),
	SqList *list)
{
	if (!compare || !list) {
		ERR_RECORD(ERR_NULL_PTR, "compare = %p, list = %p", compare, list);
		return ERR_NULL_PTR;
	}

	int pos;
	Status ret = LocateElem(list, e, compare, &pos);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = ListDelete(pos, list, &e);
	if (ret != RET_OK) {
		ERR_RECORD(ret, "pos = %d", pos);
		return ret;
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:用 e 取代表 *list 中第 i 个元素的值
*/
Status RePlaceElem(const SqList *list, int i, ElemType e)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	if ((i < 1) || (i > list->length)) {
		ERR_RECORD(ERR_NOT_EXIST, "i = %d, listLength = %d", i, list->length);
		return ERR_NOT_EXIST;
	}

	*(list->elem + i - 1) = e;

	return RET_OK;
}

4) algorithm.h

// 算法实现头文件

#ifndef ALGORITHM_H
#define ALGORITHM_H

#include "dynSqList.h"

Status Union(const SqList *listB, SqList *listA);

Status MergeList(const SqList *listA, const SqList *listB,
	int(*compare)(ElemType, ElemType), SqList *listC);

Status MergeList2(const SqList *listA, const SqList *listB,
	int(*compare)(ElemType, ElemType), SqList *listC);

Status MergeList3(const SqList *listA, const SqList *listB,
	int(*compare)(ElemType, ElemType), SqList *listC);

#endif // !ALGORITHM_H

5) algorithm.c

// 算法实现源文件

#include "algorithm.h"
#include "auxiliary.h"
#include <stdio.h>
#include <stdlib.h>

/*
	算法 2.1
	前置条件:顺序线性表 *listB 和 *listA 已存在
	操作结果:将所有在线性表 *listB 中但不在 *listA 中的数据元素插入到 *listA 中
*/
Status Union(const SqList *listB, SqList *listA)
{
	if (!listB || !listA) {
		ERR_RECORD(ERR_NULL_PTR, "listB = %p, listA = %p", listB, listA);
		return ERR_NULL_PTR;
	}

	int listALength, listBLength;
	ListLength(listA, &listALength);
	ListLength(listB, &listBLength);
	ElemType e;
	int pos;
	Status ret;

	for (int i = 1; i <= listBLength; ++i) {
		ret = GetElem(listB, i, &e);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "i = %d", i);
			return ret;
		}

		ret = LocateElem(listA, e, Equal, &pos);
		if (ret == RET_OK) {
			continue;
		}

		ret = ListInsert(++listALength, e, listA);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "listALength = %d", listALength);
			return ret;
		}
	}

	return RET_OK;
}

/*
	算法 2.2
	前置条件:线性表 *listA 和 *listB 中的数据元素按值非递减排列
	操作结果:归并 *listA 和 *listB 得到新的线性表 *listC, *listC 的数据元素也按值
			  非递减排列
*/
Status MergeList(const SqList *listA, const SqList *listB,
	int(*compare)(ElemType, ElemType), SqList *listC)
{
	if (!listA || !listB || !listC) {
		ERR_RECORD(ERR_NULL_PTR, "listA = %p, listB = %p, listC = %p",
			listA, listB, listC);
		return ERR_NULL_PTR;
	}

	Status ret = InitList(listC);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	int listALength, listBLength;
	ListLength(listA, &listALength);
	ListLength(listB, &listBLength);

	int i = 1, j = 1, k = 0;
	ElemType ai, bj;

	while ((i <= listALength) && (j <= listBLength)) {
		ret = GetElem(listA, i, &ai);
		ret |= GetElem(listB, j, &bj);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "i = %d, j = %d", i, j);
			return ret;
		}

		if (compare(ai, bj) <= 0) {
			ret = ListInsert(++k, ai, listC);
			if (ret != RET_OK) {
				ERR_RECORD(ret, "k = %d", k);
				return ret;
			}

			++i;
			continue;
		}

		ret = ListInsert(++k, bj, listC);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "k = %d", k);
			return ret;
		}

		++j;
	}

	while (i <= listALength) {
		ret = GetElem(listA, i++, &ai);
		ret |= ListInsert(++k, ai, listC);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "i = %d, k = %d", i, k);
			return ret;
		}
	}

	while (j <= listBLength) {
		ret = GetElem(listB, j++, &bj);
		ret |= ListInsert(++k, bj, listC);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "j = %d, k = %d", j, k);
			return ret;
		}
	}

	return RET_OK;
}

/*
	算法 2.7
	前置条件:顺序线性表 *listA 和 *listB 的元素按值非递减排列
	操作结果:归并 *listA 和 *listB 得到新的顺序线性表 *listC, *listC 的元素也按值非递减排列
*/
Status MergeList2(const SqList *listA, const SqList *listB,
	int(*compare)(ElemType, ElemType), SqList *listC)
{
	if (!listA || !listB || !listC) {
		ERR_RECORD(ERR_NULL_PTR, "listA = %p, listB = %p, listC = %p",
			listA, listB, listC);
		return ERR_NULL_PTR;
	}

	int listALength, listBLength, listCLength;
	ListLength(listA, &listALength);
	ListLength(listB, &listBLength);

	listCLength = listALength + listBLength;
	ElemType *pc = listC->elem = (ElemType *)malloc(sizeof(ElemType) * listCLength);
	if (!pc) {
		ERR_RECORD(ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	listC->listSize = listC->length = listCLength;
	ElemType *pa = listA->elem, *pb = listB->elem;
	ElemType *pa_last = listA->elem + listA->length - 1;
	ElemType *pb_last = listB->elem + listB->length - 1;

	while ((pa <= pa_last) && (pb <= pb_last)) {
		if (compare(*pa, *pb) <= 0) {
			*pc++ = *pa++;
			continue;
		}

		*pc++ = *pb++;
	}

	while (pa <= pa_last) {
		*pc++ = *pa++;
	}

	while (pb <= pb_last) {
		*pc++ = *pb++;
	}

	return RET_OK;
}

/*
	算法 2.7
	前置条件:顺序线性表 *listA 和 *listB 已存在
	操作结果:另一种合并线性表(元素相同时只插入一个)的方法(根据算法 2.7 下的要求
			  修改算法 2.7,仅仅在元素严格递增或递减时等同于算法 2.1)
*/
Status MergeList3(const SqList *listA, const SqList *listB,
	int(*compare)(ElemType, ElemType), SqList *listC)
{
	if (!listA || !listB || !listC) {
		ERR_RECORD(ERR_NULL_PTR, "listA = %p, listB = %p, listC = %p",
			listA, listB, listC);
		return ERR_NULL_PTR;
	}

	int listALength, listBLength, listCSize;
	ListLength(listA, &listALength);
	ListLength(listB, &listBLength);

	listCSize = listALength + listBLength;
	ElemType *pc = listC->elem = (ElemType *)malloc(sizeof(ElemType) * listCSize);
	if (!pc) {
		ERR_RECORD(ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	listC->listSize = listCSize;
	ElemType *pa = listA->elem, *pb = listB->elem;
	ElemType *pa_last = listA->elem + listA->length - 1;
	ElemType *pb_last = listB->elem + listB->length - 1;

	while ((pa <= pa_last) && (pb <= pb_last)) {
		switch (compare(*pa, *pb)) {
		case  0:
			pb++;
		case -1:
			*pc++ = *pa++;
			break;
		case  1:
			*pc++ = *pb++;
			break;
		default:
			break;
		}
	}

	while (pa <= pa_last) {
		*pc++ = *pa++;
	}

	while (pb <= pb_last) {
		*pc++ = *pb++;
	}

	listC->length = (int)(pc - listC->elem);

	return RET_OK;
}

6) auxiliary.h

// 辅助函数头文件

#ifndef AUXILIARY_H
#define AUXILIARY_H

#include "errorRecord.h"
#include "dynSqList.h"

Boolean Equal(ElemType e1, ElemType e2);

void Print(ElemType *e);

int Comp(ElemType e1, ElemType e2);

Boolean CompSquare(ElemType e1, ElemType e2);

void DoubleElem(ElemType *e);

Status CreateSqList(int n, Boolean isAscend, Compare compare, SqList *list);

Status ShowList(char str[], const SqList *list);

#endif // !AUXILIARY_H

7) auxiliary.c

// 辅助函数实现源文件

#include "auxiliary.h"
#include "dynSqList.h"

/*
	前置条件:无
	操作结果:判断两个元素是否相等
*/
Boolean Equal(ElemType e1, ElemType e2)
{
	return (e1 == e2) ? TRUE : FALSE;
}

/*
	前置条件:e 非空
	操作结果:打印元素 *e
*/
void Print(ElemType *e)
{
	printf("%d ", *e);
}

/*
	前置条件:无
	操作结果:比较元素大小
*/
int Comp(ElemType e1, ElemType e2)
{
	return (e1 == e2) ? 0 : ((e1 < e2) ? -1 : 1);
}

/*
	前置条件:无
	操作结果:判断元素之间是否存在平方关系
*/
Boolean CompSquare(ElemType e1, ElemType e2)
{
	return (e1 == e2 * e2) ? TRUE : FALSE;
}

/*
	前置条件:e 非空
	操作结果:使元素值加倍
*/
void DoubleElem(ElemType *e)
{
	*e *= 2;
}

/*
	前置条件:list 非空
	操作结果:根据 isAscend 是否为 TRUE 建立升序或者降序的具有 n 个元素的线性表
*/
Status CreateSqList(int n, Boolean isAscend, Compare compare, SqList *list)
{
	if (!list) {
		ERR_RECORD(ERR_NULL_PTR);
		return ERR_NULL_PTR;
	}

	Status ret = InitList(list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("Please input %d elements: ", n);
	ElemType e;
	scanf_s("%d", &e);

	/* 插入第 1 个元素 */
	ret = ListInsert(1, e, list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	/* 按照要求插入其他元素 */
	for (int i = 0; i < n - 1; ++i) {
		scanf_s("%d", &e);
		if (isAscend) {
			ret = InsertAscend(e, compare, list);
			if (ret != RET_OK) {
				ERR_RECORD(ret);
				return ret;
			}

			continue;
		}

		ret = InsertDescend(e, compare, list);
		if (ret != RET_OK) {
			ERR_RECORD(ret);
			return ret;
		}
	}

	return RET_OK;
}

/*
	前置条件:顺序线性表 *list 已存在
	操作结果:格式化打印顺序线性表 *list
*/
Status ShowList(char str[], const SqList *list)
{
	printf("%s", str);
	Status ret = ListTraverse(list, Print);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	putchar('\n');

	return RET_OK;
}

8) main.c

// 入口程序源文件

#include "algorithm.h"
#include "auxiliary.h"
#include <stdio.h>

int main(void)
{
	/* 算法 2.1 测试 */
	SqList listA, listB, listC;
	Status ret = InitList(&listA);
	ret |= InitList(&listB);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	for (int i = 0; i < 5; ++i) {
		ret = ListInsert(i + 1, i + 1, &listA);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "i + 1 = %d", i + 1);
			return ret;
		}
	}

	ret = ShowList("listA: ", &listA);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	for (int i = 0; i < 5; ++i) {
		ret = ListInsert(i + 1, 2 * (i + 1), &listB);
		if (ret != RET_OK) {
			ERR_RECORD(ret, "i + 1 = %d", i + 1);
			return ret;
		}
	}

	ret = ShowList("listB: ", &listB);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = Union(&listB, &listA);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = ShowList("listA: ", &listA);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	/* 算法 2.2 、2.3 测试 */
	ret = MergeList(&listA, &listB, Comp, &listC);	/* 或 MergeList2(&listA, &listB, &listC) */
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = ShowList("listC: ", &listC);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	/* 基本操作测试 */

	/* 求第一个满足条件是 2 的平方的数的位置 */
	int pos;
	ret = LocateElem(&listC, 2, CompSquare, &pos);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("pos = %d\n", pos);

	/* 依次对元素加倍并遍历元素 */
	ret = ListTraverse(&listC, DoubleElem);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = ShowList("listC: ", &listC);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	/* 销毁线性表 */
	ret = DestroyList(&listA);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = DestroyList(&listB);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = DestroyList(&listC);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	/* 测试其他 */
	SqList list;
	printf("Please input the element num of list for create ascend: ");
	int num;
	scanf_s("%d", &num);
	ret = CreateSqList(num, TRUE, Comp, &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret, "num = %d", num);
		return ret;
	}

	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = InsertAscend(10, Comp, &list);;
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("After insert 10 for ascend, ");
	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = HeadInsert(12, &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = EndInsert(9, &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("After insert 12 in the head of list, insert 9 in the tail of list, ");
	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ElemType e1, e2;
	printf("Please input the element to be delete: ");
	scanf_s("%d", &e1);
	ret = DeleteElem(e1, Equal, &list);
	printf("delete %d %s\n", e1, (ret == RET_OK) ? "success" : "failed");
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("Please input the order of the element to be replace and the new value: ");
	scanf_s("%d%d", &num, &e1);
	ret = RePlaceElem(&list, num, e1);
	if (ret != RET_OK) {
		ERR_RECORD(ret, "num = %d, e1 = %d", num, e1);
		return ret;
	}

	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = DestroyList(&list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("Create list for descend, please input the num of list: ");
	scanf_s("%d", &num);
	ret = CreateSqList(num, FALSE, Comp, &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret, "num = %d", num);
		return ret;
	}

	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = InsertDescend(10, Comp, &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	printf("After insert 10 in list for descend, ");
	ret = ShowList("list is: ", &list);
	printf("Please input the element to be delete: ");
	scanf_s("%d", &e1);
	ret = DeleteElem(e1, Equal, &list);
	printf("delete %d %s\n", e1, (ret == RET_OK) ? "success" : "failed");
	if (ret != RET_OK) {
		ERR_RECORD(ret, "e1 = %d", e1);
		return ret;
	}

	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = DeleteFirst(&list, &e1);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = DeleteTail(&list, &e2);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}


	printf("After delete head element %d and tail element %d, ", e1, e2);
	ret = ShowList("list is: ", &list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	ret = DestroyList(&list);
	if (ret != RET_OK) {
		ERR_RECORD(ret);
		return ret;
	}

	return 0;
}

3. 输出示例(DEBUG OFF)

 1)测试输入

5
1 3 2 4 5
12
6 8
5
3 2 4 5 1
2

 2)测试输出

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值