• 链表的定义


    #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 = '
    ';
    	int length = 0;
    	cout << "请输入一组" << typeid(ElemType).name() << "序列(回车结束输入):";
    	do {
    		ElemType data;
    		cin >> data;
    		InsertLinkList(linkList, ++length, data);
    		finishFlag = getchar();
    	} while (finishFlag != '
    ');
    	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	:	";
    	PrintLinkList(linkList);
    	cout << "linkList_source	:	";
    	PrintLinkList(linkList_source);
    	cout << "合并后linkList	:	";
    	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;
    }
    
    
  • 相关阅读:
    Codeforces Round #270 solution
    Codeforces Round #269 (Div. 2) solution
    Codeforces Round #268 (Div. 1) solution(upd div 1 C,div 2 A, B
    Codeforces Round #267 (Div. 2) solution
    Unity 绘制多边形
    DOTween 模仿NGUI Tween
    图像混合模式 正片叠底、滤色、叠加
    一只羊的四个月可以生一只小羊,小羊四个月后又可以生一只小羊 问50个月后有多少只羊(羊不会死)
    Unity CCTween UGUI 动画插件
    Unity UGUI 使用 CCTween 实现 打字效果
  • 原文地址:https://www.cnblogs.com/SimbaWang/p/14658681.html
Copyright © 2020-2023  润新知