简体   繁体   English

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

[英]Sorting Linked List C++ with pointers

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).我的目标是仅使用指针对链表进行排序(我不能将链表放入 vec 或数组中然后进行排序)。 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).我可以在指针上调用的唯一方法是 head->next(下一个节点)和 head->key(存储在节点中的 int 值,用于进行比较)。 I have been using my whiteboard excessively and have tried just about everything I can think of.我一直在过度使用我的白板,并尝试了我能想到的一切。

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;
}

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;
    }       
}

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;
         }
    }
}

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;
}

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;
    }

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

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;
}

Here is my Merge sort realisation, with O(N*logN) time complexity and constant additional space.这是我的合并排序实现,具有 O(N*logN) 时间复杂度和恒定的附加空间。 Uses C++11使用 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};
    }

};

Use std::list<T>::sort method.使用std::list<T>::sort方法。 Or if you're being precocious, std::forward_list<T>::sort .或者,如果您早熟,请使用std::forward_list<T>::sort

Why re-invent the wheel.为什么要重新发明轮子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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