链表的定义

#include<iostream>
#include"../../全局定义/预定义常量和类型/预定义常量和类型.cpp"
#include"../../全局定义/Compare函数的定义/Compare函数的定义.cpp"

using namespace std;

template <typename ElemType>
struct LinkNode {
	ElemType data;
	struct LinkNode<ElemType>* next;
};
#define LinkList LinkNode<ElemType>*

// 初始化链表
template <typename ElemType>
Status InitLinkList(LinkList& linkList) {
	// 建立“头结点”,并使得其next指针指向NULL
	linkList = (LinkList)malloc(sizeof(LinkNode<ElemType>));
	if (!linkList)
		exit(OVERFLOW);
	linkList->next = NULL;
	return OK;
}

// 获取链表的长度
template <typename ElemType>
int LengthOfLinkList(LinkList linkList) {
	LinkNode<ElemType>* p = linkList->next;
	int length = 0;
	while (p != NULL)
	{
		length++;
		p = p->next;
	}
	return length;
}

// 查找第order个节点的地址
template <typename ElemType>
Status LocationInOrder(LinkList linkList, int order, LinkNode<ElemType>*& p_linkNode) {
	// 判断order的合法性: [0, length]
	if (0 <= order)
	{
		int index = 0;
		LinkNode<ElemType>* cursor = linkList;
		/*
		* index < order	: 保证终止时index=order,此时p指向第order个位置
		* cursor!=NULL	: 保证第order个元素不是空【order<=length】
		* 总结:①、index<n保证指向第n个节点;②、?!=NULL确定order的最大值为:length-COUNT(next);
		*/
		while (index < order && cursor)
		{
			cursor = cursor->next;
			index++;
		}
		if (!cursor)	// 表示order>length
			return ERROR;
		else
		{
			p_linkNode = cursor;
			return OK;
		}
	}
	else
	{
		return ERROR;
	}
}

// 查找相对第order个前驱节点的地址
template <typename ElemType>
Status LocationInRelativeOrder_Prior(LinkList linkList, int relativeOrder, LinkNode<ElemType>* p_linkNode, LinkNode<ElemType>*& p_relative) {
	p_relative = NULL;

	// relativeOrder的合法性: [0, p_linkNode-1]。
	if (relativeOrder < 0)
		return ERROR;
	// 让游标指向首元结点
	LinkNode<ElemType>* cursor = linkList->next;
	int order = 1;
	// order在这一范围内跳出 → o≤r
	// 先让cursor前进relativeOrder个单位,指向relativeOrder+1,这时正好相距relativeOrder-1个单位
	while (order < relativeOrder + 1)
	{
		if (cursor == p_linkNode)
			return ERROR;
		cursor = cursor->next;
		order++;
	}

	p_relative = linkList->next;
	// 然后p_relative与cursor再一起前进直到cursor==p_linkNode,此时
	while (cursor != p_linkNode)
	{
		p_relative = p_relative->next;
		cursor = cursor->next;
	}
	return OK;
}

// 查找相对第order个后继节点的地址
template <typename ElemType>
Status LocationInRelativeOrder_Next(LinkList linkList, int relativeOrder, LinkNode<ElemType>* p_linkNode, LinkNode<ElemType>*& p_relative) {
	p_relative = NULL;
	if (relativeOrder < 0)
		return ERROR;
	int order = 0;
	p_relative = p_linkNode;
	while (order < relativeOrder)
	{
		p_relative = p_relative->next;
		order++;
		if (!p_relative)
			return ERROR;
	}
	return OK;
}

// 查找相对第order个节点的地址
template <typename ElemType>
Status LocationInRelativeOrder(LinkList linkList, int relativeOrder, LinkNode<ElemType>* p_linkNode, LinkNode<ElemType>*& p_relative) {
	return
		relativeOrder <= 0 ?
		LocationInRelativeOrder_Prior(linkList, -relativeOrder, p_linkNode, p_relative) :
		LocationInRelativeOrder_Next(linkList, relativeOrder, p_linkNode, p_relative);
}

// 查找第1个满足compare关系的data所在的位置以及索引
template <typename ElemType>
int LocationOfLinkNode(LinkList linkList, ElemType data, LinkNode<ElemType>*& p_linkNode, int (*compare)(ElemType, ElemType)) {
	LinkNode<ElemType>* cursor = linkList->next;
	int index = 1;
	while (cursor)
	{
		if (compare(cursor->data, data))
			break;
		cursor = cursor->next;
		index++;
	}
	p_linkNode = cursor;
	if (!cursor)
		index = -1;
	return index;
}

// 在链表的头部插入元素(头插法)
template <typename ElemType>
Status InsertLinkList(LinkList& linkList, ElemType data) {
	// 创建一个数据为data的新节点
	LinkNode<ElemType>* p_dataNode = (LinkNode<ElemType>*)malloc(sizeof(LinkNode<ElemType>));
	if (!p_dataNode)
		return ERROR;
	else
	{
		p_dataNode->data = data;
		// 让新节点的next指向旧节点
		p_dataNode->next = linkList->next;
		// 让头结点的next指向这个新的节点,使其成为新的第一个节点
		linkList->next = p_dataNode;
		return OK;
	}
}

// 在地址为p_linkNode的后继插入元素
template <typename ElemType>
Status InsertLinkListNext(LinkNode<ElemType>* p_linkNode, ElemType data) {
	LinkNode<ElemType>* nextNode = (LinkNode<ElemType>*)malloc(sizeof(LinkNode<ElemType>));
	if (!nextNode)
		return ERROR;
	nextNode->data = data;
	nextNode->next = p_linkNode->next;
	p_linkNode->next = nextNode;
	return OK;
}

// 在指定序号order处插入元素data
template <typename ElemType>
Status InsertLinkList(LinkList& linkList, int order, ElemType data) {
	// 找到第order-1个节点
	LinkNode<ElemType>* p_preOfOrder = NULL;
	// order-1的范围与查找函数规定的范围一致
	if (LocationInOrder(linkList, order - 1, p_preOfOrder) == OK)
	{
		LinkNode<ElemType>* p_dataNode = (LinkNode<ElemType>*)malloc(sizeof(LinkNode<ElemType>));
		if (!p_dataNode)
			return OVERFLOW;
		else
		{
			p_dataNode->data = data;

			p_dataNode->next = p_preOfOrder->next;
			p_preOfOrder->next = p_dataNode;

			return OK;
		}
	}
	else
	{
		return ERROR;
	}
}

// 在指定序号order处插入新的链表
template <typename ElemType>
Status InsertLinkList(LinkList& linkList_dest, int order, LinkList linkList_source) {
	// 判断order的合法性: [1, length+1]
	int index = order;
	LinkNode<ElemType>* p_source = linkList_source->next;
	while (p_source)
	{
		if (InsertLinkList(linkList_dest, order++, p_source->data) != OK)
			return ERROR;
		p_source = p_source->next;
	}
	return OK;
}

// 创建节点,并返回长度
template <typename ElemType>
int InputLinkNodes(LinkList& linkList) {
	char finishFlag = '\n';
	int length = 0;
	cout << "请输入一组" << typeid(ElemType).name() << "序列(回车结束输入):";
	do {
		ElemType data;
		cin >> data;
		InsertLinkList(linkList, ++length, data);
		finishFlag = getchar();
	} while (finishFlag != '\n');
	return length;
}

// 在指定序号order处删除元素
template <typename ElemType>
Status DeleteLinkNode(LinkList& linkList, int order) {
	// 找到第order-1个节点
	LinkNode<ElemType>* p_preOfOrder = NULL;
	// order-1的范围: [0, length-1];查找函数规定的范围: [0, length]
	if (LocationInOrder(linkList, order - 1, p_preOfOrder) == OK && p_preOfOrder->next) {
		// !p_preOfOrder->next:保证order-1不是第length个节点【order<length+1】
		LinkNode<ElemType>* p_del = p_preOfOrder->next;
		p_preOfOrder->next = p_del->next;
		free(p_del);
		return OK;
	}
	else
	{
		return ERROR;
	}
}

// 删除指定地址的元素
template <typename ElemType>
Status DeleteLinkNode(LinkList& linkList, LinkNode<ElemType>* node_del) {
	// 找到直接前驱
	LinkNode<ElemType>* p_prior = NULL;
	if (LocationInRelativeOrder(linkList, -1, node_del, p_prior) == OK) {
		p_prior->next = node_del->next;
		free(node_del);
	}
	else {
		return ERROR;
	}
}

// 删除指定地址的元素的直接后继
template <typename ElemType>
Status DeleteNextLinkNode(LinkList& linkList, LinkNode<ElemType>* node_del) {
	LinkNode<ElemType>* node_del_next = node_del->next;
	node_del->next = node_del_next->next;
	free(node_del_next);
}

// 将链表逆序
template <typename ElemType>
Status ReverseLinkList(LinkList& linkList) {
	// 查找第2个元素,若找不到则说明:linkList中的节点数<2
	LinkNode<ElemType>* p_second = NULL;
	if (LocationInOrder(linkList, 2, p_second) == OK) {
		// 将原有的空间变为两个链表【头结点和头指针】
		linkList->next->next = NULL;
		LinkNode<ElemType>* preCursor, * cursor;
		preCursor = cursor = p_second;
		while (preCursor)
		{
			// cursor保证后继节点有指针指向
			cursor = cursor->next;
			// 头插法插入_linkList->next指向的节点
			preCursor->next = linkList->next;
			linkList->next = preCursor;
			// _linkList向后移动一位
			preCursor = cursor;
		}
		return OK;
	}
	else
	{
		return ERROR;
	}
}

// 将两个链表合并
template <typename ElemType>
LinkList MergeLinkList(LinkList& linkList_dest, LinkList& linkList_source) {
	LinkNode<ElemType>* p_dest = linkList_dest->next, * p_source = linkList_source->next;
	LinkNode<ElemType>* p_tmp = linkList_dest;
	while (p_dest && p_source)
	{
		if (p_dest->data <= p_source->data)
		{
			p_tmp->next = p_dest;
			p_tmp = p_dest;
			p_dest = p_dest->next;
		}
		else
		{
			p_tmp->next = p_source;
			p_tmp = p_source;
			p_source = p_source->next;
		}
	}
	p_tmp->next = p_dest ? p_dest : p_source;
	free(linkList_source);
	return linkList_dest;
}

// 将链表中的所有元素打印出来
template <typename ElemType>
void PrintLinkList(LinkList linkList) {
	LinkNode<ElemType>* p = linkList;
	cout << "头结点 → ";
	while (p->next)
	{
		p = p->next;
		cout << p->data << " → ";
	}
	cout << "NULL" << endl;
}


int main() {
	// 测试用例:12 23 34 45 56 67 78 89 90
#define ElemType int
	LinkList linkList;
	InitLinkList(linkList);

	int length = InputLinkNodes(linkList);
	cout << "linkList的长度为:" << length << endl;
	cout << "linkList的元素有:";
	PrintLinkList(linkList);

	int order_del;
	order_del = 1;
	DeleteLinkNode(linkList, order_del);
	cout << "删除第" << order_del << "个节点之后:";
	PrintLinkList(linkList);
	order_del = 5;
	DeleteLinkNode(linkList, order_del);
	cout << "删除第" << order_del << "个节点之后:";
	PrintLinkList(linkList);
	order_del = 3;
	DeleteLinkNode(linkList, order_del);
	cout << "删除第" << order_del << "个节点之后:";
	PrintLinkList(linkList);

	cout << "linkList逆序输出: ";
	ReverseLinkList(linkList);
	PrintLinkList(linkList);

	LinkNode<ElemType>* p_linkNode = NULL, * p_relativePrior = NULL, * p_relativeNext = NULL;
	int coreOrder = 3;
	LocationInOrder(linkList, coreOrder, p_linkNode);
	LocationInRelativeOrder(linkList, -2, p_linkNode, p_relativePrior);
	LocationInRelativeOrder(linkList, 2, p_linkNode, p_relativeNext);
	cout << "相对核心位置" << coreOrder << "为-2:" << p_relativePrior->data << endl;
	cout << "相对核心位置" << coreOrder << "为+2:" << p_relativeNext->data << endl;

	cout << "删除第" << coreOrder << "个结点(" << p_linkNode->data << ")之后:";
	DeleteLinkNode(linkList, p_linkNode);
	PrintLinkList(linkList);
#undef ElemType

#define ElemType int
	LinkList linkList_source;
	InitLinkList(linkList_source);
	InsertLinkList(linkList_source, 3);
	InsertLinkList(linkList_source, 2);
	InsertLinkList(linkList_source, 1);
	cout << "linkList\t:\t";
	PrintLinkList(linkList);
	cout << "linkList_source\t:\t";
	PrintLinkList(linkList_source);
	cout << "合并后linkList\t:\t";
	InsertLinkList(linkList, 2, linkList_source);
	PrintLinkList(linkList);

	LinkNode<ElemType>* p = NULL, * p_linkNode_2 = NULL;
	LocationInOrder(linkList, 2, p);
	cout << "第2个位置的元素为:" << p->data << endl;
	cout << "第1个" << p->data << "的位置为:" << LocationOfLinkNode(linkList, p->data, p_linkNode_2, Equal) << endl;
#undef ElemType

	return 0;
}

posted @ 2021-04-14 16:41  BNTU  阅读(201)  评论(0编辑  收藏  举报