链表排序(1)

前些天在论坛看到个帖子, 关于链表排序。

我首先想到的是, 将链表中的成员(member)进行交换, 这对于单成员来说方法是非常好的。 当链表的元素比较多, 而且结构复杂, 移动所有元素就不明智了。想象一下 Facebook 这么多的用户,用户属性又这么多,如果排序采取属性移动到特定空间的方法。这是多么吓人。

这时, 我们需要考虑采取移动链表指向的方法。 好比重新链接这个链条一样。 这个方法的好处之一可以解决上诉提到的类似 Facebook 成员链表中多属性(member)问题。

还有一个好处, 那就是按任意属性比较方式来排序(比如,身高比, 一种排序方式, 体重比一种排序方式), 而不需要移动其它元素, 节省大量空间时间。

上述两种方法好比搬家,换门牌号。 换门牌号当然轻松多了, 不过实际生活中, 人们不会这么干。 但是对于电脑处理链表来说, 就是顺藤摸瓜。 所以, 换门牌号简单。

现在讲讲第二个排序方法(第一个简单, 不再讲了)

采用的是冒泡排序, 但是由于链表不像数值那样自由访问, 必须先找到根(这里用 first 指向链表的第一个元素(根元素)), 不从根开始摸, 是不知道在哪里结尾的。 所以这次的冒泡排序(应称沉淀排序, 不过实质一样)是先找出最大的, 沉到最低。同时由于根访问特性, 使得一种更快的排序----------归并排序相当繁琐, 需要复制用来比较的成员和元素地址各一份, 故对于链表来说, 归并排序不见得优秀。

下面是其实现代码, 如果要完整的能运行的话。问我(1220645790,  或者看这里

void SortList(void);
void swap(node *left, node *middle, node *right);

void SortList(void)
{
	/********************************************************************************************
	* 1. "compare" use for compare
	* 2. "iterate" use for traversal, alway in front one position of "compare" before compare swap
	* 3. "last" use to mark the position which alreay sorted, maybe you can instead by "NULL", but
	* 		the number of comparisons will be times 2
	*********************************************************************************************/
	node *compare, *iterate, *last;

	last = NULL;	
	while (last != first->next)
	{
		// first elements as compare, mark(iterate) = NULL
		compare = first;
		iterate = NULL;
		if (compare->n > compare->next->n)
			swap(iterate, compare, compare->next);
		
		// not first element as compare, mark(that is iterate) = previous of compare
		for (iterate = first; iterate->next->next != last; iterate = iterate->next)
		{
			compare = iterate->next;
			if (compare->n > compare->next->n)
				swap(iterate, compare, compare->next);
				
		}
		
		last = iterate->next;
	}
	
}


void swap(node *left, node *middle, node *right)
{
	if (left == NULL)
	{
		first = right;
		middle->next = right->next;
		right->next = middle;
	}
	else
	{	left->next = right;
		middle->next = right->next;			// right->next must be last assignment, 
		right->next = middle;				// if not, may be lead to the last element's member "next" != "NULL"
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值