我编写了一个代码,按排序顺序将新的随机数添加到链表中。看起来它工作正常但与我所看到的不同。
你可以看一下,从内存消耗的位置来看它是否有效吗?
我还听说如果要使用指向当前数字位置的指针(指向位置指针的指针)对列表进行排序,那么它会 是最有效的算法。是这样吗?
void add (num*&head, int size) {
num*temp = head;
num*prev = 0;
num*first = head;
int n;
int min = 0;
for (int i = 0; i<size; i++){
num*node = new num;
node->n = rand()%100;
cout << node->n << endl;
if (head!=0) {
if (prev != 0) {
if (node->n < head->n){
if (node->n < first->n) {
node->next = 0;
first->next = node;
first = node;
}
else {
temp = head;
while (temp->next != 0)
{
if (node->n <= temp->n && node->n >= temp->next->n) {
node->next = temp->next;
temp->next = node;
temp = head;
break;
}
else {
temp = temp->next;
}}}}
else
{
node->next = head;
head = node;
temp = head;
}}
else {
if (node->n < temp->n){
node->next = 0;
temp->next = node;
prev = node;
first = prev;
}
else {
node->next = head;
head = node;
prev = node->next;
first = prev;
}}}
else {
node->next = head;
head = node;
temp = head;
first = head;
}}}
答案 0 :(得分:1)
如果您的算法遵循MDo在评论中描绘的算法,则可以使用较少的比较来搜索正确的位置(通过使用比仅仅一个元素更大的步骤并在您回家时减小步长)。但是,当使用链表时,这不会使代码更快,因为列表的遍历仍然需要访问每个单独的元素,直到找到正确的位置(到目前为止所有元素的平均一半)。这将产生相同数量的缓存未命中( 效率杀手)作为更简单的算法。因此,在添加随机元素的同时保持链表的排序不能有效地完成。
可以有效地完成是将列表保留在heap order中,而adding random elements(每个成本为O(log N))。最后,在添加所有元素之后,从堆顺序快速obtain a sorted order可以直接进行。
实际上,堆排序算法以这种方式工作:首先将随机顺序排列成堆顺序,然后获得排序顺序(平均效率略低于快速排序)。
答案 1 :(得分:1)
事实上,这个算法是插入排序(通过小优化,查找最后排序的元素)。
可以实现消耗更少的内存。您可以使用一些内存来维护列表 - 指向下一个元素的指针,指向尾部的指针等。 你不是真的需要它,因为一个简单的数组会提供相同的功能,但消耗更少的内存。
@Walter已经提到堆,但还有其他现代排序算法,如块排序,它们都是就地 AND 稳定。