如何将代码更改为交换指针而不是使用“临时”指针?

Posted

技术标签:

【中文标题】如何将代码更改为交换指针而不是使用“临时”指针?【英文标题】:How to change the codes into swapping pointers instead of using "temp" pointer? 【发布时间】:2015-09-03 14:29:33 【问题描述】:

下面是我使用链表进行选择排序的部分代码。但是,我已经问过我的导师,他告诉我不要使用“temp”来更改代码,而是交换指针。因此,我在这里寻求有关如何不使用临时但将其更改为交换指针的帮助? :) 谢谢。

void List::SelectionSort()
nodePtr last = NULL;
int temp = 0;
int max = 0;
count = 0;
count = CalculateData();


while(count > 1)
    curr = head;
    nodePtr Biggest = NULL;
    Biggest = curr;
    max = curr->data;

    for(int i=0; i<count-1; i++)
        if(max < curr->data)
            max = curr->data;
            //cout << "biggest data" << max << endl;
            Biggest = curr;
        

           // cout << "biggest data" << max << endl;
           // cout << "curr data" << curr->data << endl;
            curr = curr->next;
            last = curr;
    //end for
    if(last->data > max)
       max = last->data;
    

    if(Biggest->data == max)
        temp = last->data;
        last->data = max;
        Biggest->data = temp;
        GetConsoleScreenBufferInfo( hstdout, &csbi );//color only ignore this
        SetConsoleTextAttribute( hstdout, 0x1B ); //color only ignore this
        cout << "swapped " << Biggest->data << " with " << last->data << endl;
        SetConsoleTextAttribute( hstdout, csbi.wAttributes );//color only ignore this
    else
        GetConsoleScreenBufferInfo( hstdout, &csbi );//color only ignore this
        SetConsoleTextAttribute( hstdout, 0x1B ); //color only ignore this
        cout << "swapped " << last->data << " with " << last->data << endl;
        SetConsoleTextAttribute( hstdout, csbi.wAttributes );//color only ignore this
    

//cout << "count " << count << " ";
//cout << "last " << last->data << " ";
//cout << "biggest " << Biggest->data << endl;

PrintData();
cout << endl;
count--;

//end while
cout << endl;

【问题讨论】:

如果您在使用键盘之前拿出铅笔和纸并画出您需要做的事情,这会容易得多。 (交换本身将使用完全相同的方法,但如果元素很大,交换指针会更有效。) 是的,我按照您的建议做了,但仍然无法正常工作,这就是我的问题出现在这里的原因:v 【参考方案1】:

要交换指针,您需要指向指针的指针。所以你需要主要使用nodePtr*而不是nodePtr

您需要从头开始,例如: nodePtr* curr = &amp;head; 那么您将主要使用(*curr) 而不是curr 你可以用curr = &amp;(*curr)-&gt;next;推进指针

一旦你有了指向你需要交换的指针的指针,你就可以用 std::swap() 交换它们

【讨论】:

【参考方案2】:

在这段代码中:

temp = last->data;
last->data = max;
Biggest->data = temp;

您正在交换数据,而不是列表的节点。你的导师希望你交换节点。这意味着您必须重新链接您的列表。不知道你的节点是怎么定义的;如果它是一个双向链表,那么它很容易,在这种情况下它应该是这样的:

nodePtr biggestPrev = Biggest->prev;
nodePtr biggestNext = Biggest->next;

// this pseudocode puts Biggest in place of last
nodePtr tmp = last->prev->next; 
last->prev->next = Biggest;
Biggest->prev = last;
Biggest->next = tmp;
tmp->prev = Biggest;

// This pseudocode puts last in place of Biggest
biggestPrev->next = last;
last->prev = biggestPrev;
bigestNext->prev = last;
last->next = biggestNext;

这是一个伪代码,不考虑终端情况(例如空节点)。如果您的列表是单链接的,那么它的工作量更大;您将需要迭代列表并决定重新链接哪些元素。

【讨论】:

如果你看一下 head 的使用方式,你会发现你的双向链表解决方案即使是双向链表也不起作用(因为 head 是指针而不是节点并且指向真正的第一个节点,而不是虚拟节点)。无论如何,对于双向链表来说,head 的使用会相当蹩脚,所以它更有可能是一个单链表。 @JSF 我不确定我是否理解你,Biggest 和 last 都是 nodePtr 类型,并且是指针。另外我认为这是进行交换的正确位置。 OP问导师要求什么样的交换,所以我的回答是给出 - 也许不是确切的答案 - 但提示如何解决这个问题。剩下的作业留给 OP。【参考方案3】:

我不会给你代码,而是一个插图。 (编写代码是一种很好的做法,不是很困难。)

这是列表的两部分的图片,在交换 A 和 B 的位置之前和之后:

如您所见,您需要交换两对指针,而不是一对。 (当元素大于整数时,交换指针更有意义。)

【讨论】:

谢谢。 :) 我需要的只是指南,我希望我能自己做。【参考方案4】:

在选择排序中,您选择要移动的元素。由于这是一个数组,因此您要移动的元素是节点,而不是节点中的数据。你不需要换。可以说,这会使您的选择排序表现得更像插入排序,但实际上您只是利用了数据结构的属性。

所以在高层次上:

SelectionSort(inputList)
    outputList : initially empty
    while not empty(inputList)
        (biggestNode, predecessor) = findBiggestNode(inputList)
        removeNode(inputList, biggestNode, predecessor)
        insertAtHead(outputList, biggestNode)
    inputList = outputList

一些高级 C++ 代码:

// Find biggestNode and its predecessor
biggestNode = head;
predecessor = &head;
curr = &head->next;
while (*curr) 
    if ((*curr)->data > biggestNode->data) 
        biggestNode = *curr;
        predecessor = curr;
    
    curr = &(*curr)->next;


/* Removing biggestNode */
*predecessor = biggestNode->next;

/* Insert biggestNode to head of output */
biggestNode->next = outHead;
outHead = biggestNode;

Demo

【讨论】:

感谢大家给我指导。 :)

以上是关于如何将代码更改为交换指针而不是使用“临时”指针?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Vuetify组件中将光标默认更改为指针

C语言中如何交换两个指针变量的的值

捕获空指针异常是代码异味吗?

将光标更改为标签内跨度上的指针

如何让 perf 脚本将字符串参数显示为文本而不是指针值?

将光标更改为手指指针