如何将代码更改为交换指针而不是使用“临时”指针?
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 = &head;
那么您将主要使用(*curr)
而不是curr
你可以用curr = &(*curr)->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
【讨论】:
感谢大家给我指导。 :)以上是关于如何将代码更改为交换指针而不是使用“临时”指针?的主要内容,如果未能解决你的问题,请参考以下文章