[英]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.