使用指针对链表 C++ 进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19579587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:58:56  来源:igfitidea点击:

Sorting Linked List C++ with pointers

c++sortingpointers

提问by dclark

I have been struggling for hours on end with this problem. My goal is to sort a linked list using only pointers (I cannot place linked list into vec or array and then sort). I am given the pointer to the head node of the list. The only methods i can call on the pointers are head->next (next node) and head->key (value of int stored in node, used to make comparisons). I have been using my whiteboard excessively and have tried just about everything I can think of.

我一直在为这个问题苦苦挣扎数小时。我的目标是仅使用指针对链表进行排序(我不能将链表放入 vec 或数组中然后进行排序)。我得到了指向列表头节点的指针。我可以在指针上调用的唯一方法是 head->next(下一个节点)和 head->key(存储在节点中的 int 值,用于进行比较)。我一直在过度使用我的白板,并尝试了我能想到的一切。

Node* sort_list(Node* head)
{
   Node* tempNode = NULL;
   Node* tempHead = head;
   Node* tempNext = head->next;

   while(tempNext!=NULL) {

       if(tempHead->key > tempNext->key) {
           tempNode = tempHead;
           tempHead = tempNext;
           tempNode->next = tempNode->next->next;
           tempHead->next = tempNode;
           tempNext = tempHead->next;
           print_list(tempHead);


        }
        else {  
            tempHead = tempHead->next;
            tempNext = tempNext->next;

        }
    }
    return head;
}

回答by ninMonkey

Since it's a singly linked list, we can do: (psuedo code)

既然是单向链表,我们可以这样做:(伪代码)

bool unsorted = true;
while(unsorted) {
    unsorted = false;
    cur = head;         

    while(cur != nullptr) {
        next = cur->next;
        if(next < cur) {
            swap(cur, next)
            unsorted = true;
        }

        cur = cur->next;
    }       
}

回答by Riddance

Assume the Node like this:

假设节点是这样的:

struct Node
{
    Node *next;
    int key;
    Node(int x) : key(x), next(NULL) {}
};

use insertion sort algorithm to sort the List:

使用插入排序算法对列表进行排序:

Node* sort_list(Node* head)
{
    Node dumy_node(0);
    Node *cur_node = head;

    while (cur_node)
    {
        Node *insert_cur_pos =  dumy_node.next;
        Node *insert_pre_pos = NULL;

        while (insert_cur_pos)
        {
            if (insert_cur_pos->key > cur_node->key)
                break;

            insert_pre_pos = insert_cur_pos;
            insert_cur_pos = insert_cur_pos->next;
        }

        if (!insert_pre_pos)
            insert_pre_pos = &dumy_node;

        Node *temp_node = cur_node->next;

        cur_node->next = insert_pre_pos->next;
        insert_pre_pos->next = cur_node;

        cur_node = temp_node;
    }

    return dumy_node.next;
}

回答by Dweeberly

Don't feel bad this is a lot harder than it sounds. If this were in an array it would be considerably easier. If the list were doubly linked it would be easier. Take a look at this code, it implements an insertion sort

不要难过,这比听起来要困难得多。如果这是在一个数组中,它会容易得多。如果列表是双向链接的,那就更容易了。看一下这段代码,它实现了插入排序

struct Node {
    int key;
    Node *next;
    } *NodePtr;

// do a simple selection sort http://en.wikipedia.org/wiki/Selection_sort
Node* sort_list(Node* head) {
    Node *top = nullptr; // first Node we will return this value
    Node *current = nullptr;
    bool sorted = false;
    while (sorted == false) {
        // we are going to look for the lowest value in the list
        Node *parent = head;
        Node *lowparent = head; // we need this because list is only linked forward
        Node *low = head; // this will end up with the lowest Node
        sorted = true;
        do {
            // find the lowest valued key
            Node* next = parent->next;
            if (parent->key > next->key) {
                lowparent = parent;
                low = next;
                sorted = false;
                }
            parent = parent->next;
            } while (parent->next != nullptr);
        if (current != nullptr) { // first time current == nullptr
            current->next = low;
            }
        // remove the lowest item from the list and reconnect the list
        // basically you are forming two lists, one with the sorted Nodes 
        // and one with the remaining unsorted Nodes
        current = low;
        if (current == head) { head = current->next; }
        lowparent->next = low->next;
        current->next = nullptr;
        if (top == nullptr) {
            top = current;
            }
        };
    current->next = head;
    return top;
    }

int _tmain(int argc, _TCHAR* argv []) {
    Node nodes[4];
    nodes[0].key = 3;
    nodes[1].key = 4;
    nodes[2].key = 5;
    nodes[3].key = 1;

    nodes[0].next = &nodes[1];
    nodes[1].next = &nodes[2];
    nodes[2].next = &nodes[3];
    nodes[3].next = nullptr;

    auto sortedNodes = sort_list(&nodes[0]);

    return 0;
    }

回答by Sarp Kaya

Use a recursive approach as it is the easiest way of dealing with linked structures:

使用递归方法,因为它是处理链接结构的最简单方法:

Pseudocode:

伪代码:

SORT(head)
if (head->next == null) 
    return
tempNode = head->next
SORT(tempNode)
if (tempNode->value < head->value) 
    SWAP(head, tempNode)
    SORT(head)
return

so the let's say you have 5 4 3 2 1

所以假设你有 5 4 3 2 1

1) 5 4 3 1 2

1) 5 4 3 1 2

2) 5 4 1 3 2

2) 5 4 1 3 2

3) 5 4 1 2 3

3) 5 4 1 2 3

4) 5 1 4 2 3

4) 5 1 4 2 3

5) 5 1 2 4 3

5) 5 1 2 4 3

...

...

n) 1 2 3 4 5

n) 1 2 3 4 5

回答by ExtraSmart

int swapNode( node * &first, node * &second)
 {
    //first we will declare the 
    //previous of the swaping nodes
    node *firstprev=NULL;
    node*secprev=NULL;
    node*current=head;
    //set previous first
    while(current->next!=first)
    {
        current=current->next;
    }
    firstprev=current;
    //seting 2nd previous
    while(current->next!=second)
    {
        current=current->next;
    }

// swap datas, assuming the payload is an int:
int tempdata = first->data;
first->data = second->data;
second->data = tempdata;
//swaping next of the nodes
firstprev->next=second;
secprev->next=first;
}

回答by Tokhchukov Aslan

Here is my Merge sort realisation, with O(N*logN) time complexity and constant additional space. Uses C++11

这是我的合并排序实现,具有 O(N*logN) 时间复杂度和恒定的附加空间。使用 C++11

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

typedef pair<ListNode*, ListNode*> PP;

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if (head==nullptr)return head;
        if (head->next==nullptr) return head;
        if (head->next->next==nullptr){
            if (head->val<=head->next->val){
                return head;
            }
            else {
                ListNode* second=head->next;
                second->next=head;
                head->next=nullptr;
                return second;
            }
        }else {
            PP splitted=split(head);
            return merge(sortList(splitted.first),sortList(splitted.second));
        }
    }

private:  

    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode * head=new ListNode(0);
        ListNode * current=head;
        if (l1==nullptr)return l2;
        if (l2==nullptr)return l1;
        do {
            if (l1->val<=l2->val){
                current->next=l1;
                l1=l1->next;
            }else{
                current->next=l2;
                l2=l2->next;
            }
            current=current->next;
        }while (l1!=nullptr && l2!=nullptr);
        if (l1==nullptr)current->next=l2;
        else current->next=l1;
        return head->next;
    }

    PP split(ListNode* node){
        ListNode* slow=node;
        ListNode* fast=node;
        ListNode* prev;
        while(fast!=nullptr){
            if (fast->next!=nullptr){
                prev=slow;
                slow=slow->next;
                fast=fast->next;
            }else break;
            if(fast->next!=nullptr){
                    fast=fast->next;
                }
            else break;            
        }
        prev->next=nullptr;
        return {node,slow};
    }

};

回答by Shahroon Farooqi

I know its late but I also search for it but didn't get one so I make my own. maybe it will help someone. I am using bubble sort (kind of sort algorithm) to sort data in a single linked list. It just swapping the data inside a node.

我知道它晚了,但我也在寻找它,但没有找到,所以我自己做。也许它会帮助某人。我正在使用冒泡排序(一种排序算法)对单个链表中的数据进行排序。它只是交换节点内的数据。

void sorting(){
        Node* cur1 = head;
        Node* cur2 = head;

       for (int i = 0; i < getSize(); i++) {
        for (int j = 0; j < getSize() - 1; j++) {
            if (cur1->data < cur2->data) {
                int temp = cur1->data;
                cur1->data = cur2->data;
                cur2->data = temp;

            }
            cur2 = cur2->next;
        }
         cur2 = head;
         cur1 = head->next;
         for (int k = 0; k < i; k++) {
                cur1 = cur1->next;
         }
    }
}