2

我一直在努力解决这个问题几个小时。我的目标是仅使用指针对链表进行排序(我不能将链表放入 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;
}
4

8 回答 8

2

由于它是一个单链表,我们可以这样做:(伪代码)

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;
    }       
}
于 2013-10-25T01:52:20.153 回答
2

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

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;
         }
    }
}
于 2018-12-02T17:14:00.863 回答
0
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;
}
于 2014-09-25T18:30:38.707 回答
0

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

伪代码:

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

所以假设你有 5 4 3 2 1

1) 5 4 3 1 2

2) 5 4 1 3 2

3) 5 4 1 2 3

4) 5 1 4 2 3

5) 5 1 2 4 3

...

n) 1 2 3 4 5

于 2013-10-25T03:58:35.633 回答
0

假设节点是这样的:

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

使用插入排序算法对 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;
}
于 2013-10-25T03:16:43.117 回答
0

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

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;
    }
于 2013-10-25T03:24:39.490 回答
0

这是我的合并排序实现,具有 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};
    }

};
于 2018-05-17T05:45:18.980 回答
0

使用std::list<T>::sort方法。或者如果你早熟,std::forward_list<T>::sort.

为什么要重新发明轮子。

于 2021-08-10T13:00:54.413 回答