欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

stl中list的sort()函数解析

程序员文章站 2024-03-14 21:55:41
...

list不能使用STL算法sort(),必须使用自己的sort()member function,因为STL算法sort()只接受RandomAccessIterator,而list提供的是

Bidirectional Iterators


算法描述:

template<class T>
	void list<T>::sort() {
		sort(WKstl::less<T>());
	}
	template<class T>
	template<class Compare>
	void list<T>::sort(Compare comp) {
		if (empty() || head.p->next == tail.p)
			return;
		list carry;
		list counter[64];
		int fill = 0;
		while (!empty()) {
			carry.splice(carry.begin(), *this, begin());
			int i = 0;
			while (i < fill && !counter[i].empty()) {
				counter[i].merge(carry, comp);
				carry.swap(counter[i++]);
			}
			carry.swap(counter[i]);
			if (i == fill)
				++fill;
		}
		for (int i = 0; i != fill; ++i) {
			counter[i].merge(counter[i - 1], comp);
		}
		swap(counter[fill - 1]);
	}
}
步骤一:

list carry;
list counter[64];

这是一些空链表,用于辅助操作

*this是待排序的list

stl中list的sort()函数解析

步骤二:

carry.splice(carry.begin(),*this,begin());

每次都是将*this链表中的首元素移入空链表carry中,并在*this中删除移走的元素

stl中list的sort()函数解析

步骤三:

现在i=fill=0,不满足while (i < fill && !counter[i].empty())

执行carry.swap(counter[0]);

然后将fill置为1

stl中list的sort()函数解析 

这样一次while(!empty())执行完毕,开始下一轮

步骤一:

carry.splice(carry.begin(),*this,begin());

同上,将*this中的首元素拼接到carry中

stl中list的sort()函数解析

步骤二:

counter[0].merge(carry,comp);

此时,进入内层while循环,将链表carry中的元素合并(按comp方式进行合并,比如<)到counter[0]中

carry.swap(counter[i++]);

将链表carry与counter[0]进行交换

stl中list的sort()函数解析

步骤三:

现在i=fill=1,不满足while (i < fill && !counter[i].empty())

执行carry.swap(counter[1]);

然后将fill置为2

stl中list的sort()函数解析



最后对3的处理也是同理

stl中list的sort()函数解析

总之,每次执行完一次while,链表carry总是为空链表,而链表counter[i]中存放目前sort好的元素,链表list[i-1]...list[0]为空链表。直到最后把所有元素都按照comp方式排好序

最后,swap(counter[fill-1]);

也就是把排好序的所有元素再换回*this中

stl中list的sort()函数解析