顺序线性表的实现

顺序线性表的实现

/*
* 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;
}
posted @ 2021-04-14 16:29  BNTU  阅读(92)  评论(0编辑  收藏  举报