数据结构学习记录(三)链表的选择排序排序操作

在上一篇博文中,我写过了根据下标进行链表元素交换的函数(并且不能交换头结点),这次由于选择排序需要用到交换元素这个功能,于是我写下了,一个全新的交换函数(整个节点的交换)。它可以根据两者的指针值来进行交换操作。

单链表交换两个节点有一个非常值得注意的地方,指针值十分容易混乱。所以我们用图解来讲解整个过程原理:

如下图为一个单链表:

首先,当链表为空或两个需要交换的元素为同一个节点时,不进行操作。接下来交换分为以下几种情况,当p1或p2中有一个是头指针时且另一个指针是它的下一个(即两个相邻),我们把头指针拟定为p1,若p2为头指针,则交换p1与p2的值,这样p1就总是头指针,只需写一个p1为头指针交换的操作了。

先把p2的值赋给头(p2就成为了头),在定义变量post2记住p2的后一个节点的指针,在把p1的值赋给p2的next(即让p2指向p1),p1在指向post2,这样就完成了交换操作。

还有p1不和p2相邻的情况,先对链表进行遍历,找到p2的前驱节点pPos2,然后类似,使用post2变量将p2的next存起来,将p2赋给p1,让p2指向p1的next,让pPOs2指向p1,p1指向post2。交换就成功了。

5

还剩一种情况就是比较普遍的现象,即p1与p2都不为头节点,与上述情况类似,分为相邻的情况与不相邻的情况,只不过需要遍历查找p1与p2的前驱节点pPos1与pPos2。剩下的操作与上面一样交换就行了。

 

通过上述的讲解,应该大概能够理清交换操作的原理了吧。

如果还是不懂怎么敲代码的的话,源代码再这:

交换函数的具体源代码如下:

/*
函数名   :SwapLinkListByp
功能描述 :单链表根据指针交换两个元素
输入     :s1,已存在的单链表
输出     :成功返回 true ,失败返回false
全局变量 :无
调用模块 :
作者     :zhang·haochen
日期     :2019 - 01 - 23
修改     :
修改日期 :
版本     :ver 0.1
*/
//单链表交换两个元素根据指针(可以交换头结点)
bool SwapLinkListByp(LinkList* s1, LinkList p1, LinkList p2)
{
	if (*s1 == NULL || p1 == p2)
		return false;
	if (p1 == *s1 || p2 == *s1)
	{
		if (p2 == *s1)
		{
			NODE* t=p1;
			p1 = p2;
			p2 = t;
		}
		if (p1 == *s1&&p1->next == p2)
		{
			NODE* post2;		//定义变量记住p2的下一个指针
			post2 = p2->next;
			*s1 = p2;
			p2->next = p1;
			p1->next = post2;
			return true;
		}
		if (p1 == *s1&&p1->next != p2)
		{
			NODE* pPos = *s1;			//定义查找指针(查找p2的前一个节点)
			while (pPos->next != p2)
			{
				pPos = pPos->next;
			}
			NODE* post2;
			post2 = p2->next;
			//从此处交换
			*s1 = p2;
			p2->next = p1->next;
			pPos->next = p1;
			p1->next = post2;
			return true;
		}
		
	}
	else
	{
		if (p2->next == p1)
		{
			NODE* t = p2;
			p2 = p1;
			p1 = t;
		}
		NODE* pPos, *post1, *post2, *pPos1, *pPos2;
		pPos=*s1,pPos1 = *s1, pPos2 = *s1, post1 = p1->next, post2 = p2->next;
		while (pPos1->next != p1||pPos2->next != p2)
		{
			if (pPos->next == p1)
				pPos1 = pPos;
			if (pPos->next == p2)
				pPos2 = pPos;
			pPos = pPos->next;
		}
			
			if (p1->next == p2)
			{
				pPos1->next = p2;
				p2->next = p1;
				p1->next = post2;
				return true;
			}
			pPos1->next = p2;
			p2->next = post1;
			pPos2->next = p1;
			p1->next = post2;
			return true;
	}
}

有了这款交换函数,那单链表的交换,就如鱼得水了。

接下来是排序操作

/*
函数名   :LinkListChooseSort
功能描述 :单链表选择排序
输入     :s1,已存在的单链表
输出     :无
全局变量 :无
调用模块 :
作者     :zhang·haochen
日期     :2019 - 01 - 23
修改     :
修改日期 :
版本     :ver 0.1
*/
void LinkListBuddleSort(LinkList* s1)
{
	if (*s1 == NULL||(*s1)->next==NULL)
		return;
	//定义起始对比指针与当前比较的尾指针
	NODE* tail=(*s1)->next;
	NODE* head = *s1;
	while (head->next!=NULL)
	{
			
		while (1)	
		{	
			if (tail->data < head->data)
			{
				SwapLinkListByp(s1, head, tail);
				NODE* t = head;
				head = tail;
				tail = t;
				tail = tail->next;
			}
			else if (tail->data > head->data)
			{
				tail = tail->next;
			}
			if (tail == NULL)
				break;
		}
		head = head->next;
		tail = head->next;
	}
}

调用这两个函数,就可以完成对单链表的排序工作。

你可能感兴趣的:(学习记录,经验分享,互动交流,单链表排序,数据结构,C\C++)