简体   繁体   中英

How to change the codes into swapping pointers instead of using “temp” pointer?

below is a part of my codes where I have done for the Selection Sort using linked list. However, I've asked my tutor and he told me to change the code by not using "temp" but swap the pointers instead. Therefore, I'm seeking for help here on how to not use the temp but change it into swapping the pointers? :) Thanks.

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;

}

To swap the pointers, you need pointers to the pointers. So you need to work mainly with nodePtr* rather than nodePtr

You need to start out from head with something such as: nodePtr* curr = &head; then you would mostly use (*curr) instead of curr You would advance the pointer with curr = &(*curr)->next;

Once you have pointers to the pointers that you need swapped, you can swap them with std::swap()

in this code:

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

you are swapping data, and not nodes of your list. Your tutor wants you to swap nodes. This means you must relink your list. I don't know how your node is defined; if it is a doubly-linked list then it's quite easy, in this case it should look like:

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;

this is a pseudocode, no terminal cases (such as null nodes) are considered. If your list is singly-linked then it's more work; you will need to iterate the list and decide which elements to re-link.

I'm not going to give you code, but an illustration.
(Writing the code is good practice and not very difficult.)

Here's a picture of two parts of a list, before and after switching the places of A and B:

在此处输入图片说明

As you see, you need to swap two pairs of pointers, not one.
(Swapping the pointers makes more sense when the elements are bigger than integers.)

In a selection sort, you choose an element to move. Since this is an array, the elements you are moving are the nodes, not the data in the nodes. You don't need to swap. Arguably, this makes your selection sort behave more like insertion sort, but really you are just leveraging the properties of the data structure.

So on a high level:

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

Some high level C++ code:

// 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM