对单个字符串排序
Problem statement:
问题陈述:
Given a singly linked list which is ordered in terms of absolute value. Return the sorted linked list in ascending order (based on their original values). No additional storage should be used.
给定一个单链表,它按绝对值排序。 以升序返回排序的链表 (基于其原始值)。 不应使用其他存储。
Example:
例:
Given the linked list: 1->2-> -3->4-> -5->NULL
After ordering based on original values output will be:
-5 -> -3 -> 1 ->2->4->NULL
Given the linked list: 1->2->3->4->5->6->NULL
After ordering based on original values output will be:
1->2->3->4->5->6->NULL
Solution:
解:
The problem can be solved using the following concept:
可以使用以下概念解决问题:
We will make two lists out of the single linked list, say list1 and list2.
我们将从单个链接列表中列出两个列表,分别是list1和list2 。
list1 be the list of non-negative nodes as per their order. So list1 is sorted already.
list1是按顺序排列的非负节点的列表。 所以list1已经排序。
list2 be the list of negative valued nodes as per their order. Since sorted according to absolute values, list2 is actually sorted in descending order. In the other sense reverse of list2 is sorted in ascending order.
list2是按值排序的负值节点的列表。 由于是根据绝对值排序的,因此list2实际上是按降序排序的。 换句话说 , list2的反向按升序排序。
Now we need to append list1 to the reversed list2.
现在我们需要将list1附加到反向的list2上 。
This results in the original sorted list.
这将导致原始排序列表。
So the basic algorithm is:
因此基本算法是:
Construct list1 & list2 from the original list.
从原始列表构造list1 & list2 。
Reverse the list2.
反转列表2 。
Append list1 to reverse (list2).
将list1追加为反向( list2 )。
This results in the ordered list (ascending order).
这将导致排序列表(升序)。
1. Constructing list1 & list2 out of list
1.从列表中构造list1和list2
This can be done by traversing the list and checking node values. If the current node is a non-negative node, append it to the list1 else append it to the list2.
这可以通过遍历列表并检查节点值来完成。 如果当前节点是非负节点,则将其附加到list1,否则将其附加到list2 。
//posi: pointer to construct the List1
//nega: pointer to construct the List1
//store1: head to list1
//store2: head to list2
Node* posi=NULL,*nega=NULL;
Node* store1=NULL,*store2=NULL;
int countp=0,countn=0;
while(temp){ //temp is the current node of original list
if(temp->data>=0 && countp==0){//finding first node of list1
posi=temp;
store1=posi;
countp++;
temp=temp->next;
}
else if(temp->data>=0){//for other nodes of list1
posi->next=temp;
posi=posi->next;
temp=temp->next;
}
else if(temp->data<0 && countn==0){//finding first node of list2
nega=temp;
store2=nega;
countn++;
temp=temp->next;
}
else if(temp->data<0){ //for other nodes of list2
nega->next=temp;
nega=nega->next;
temp=temp->next;
}
}
if(posi)
posi->next=NULL;
if(nega)
nega->next=NULL;
2. Reverse the list2 //If list2 is constructed then only
2.反转list2 //如果构造了list2,则仅
So the list has been split to list1 and list2 ( store1 and store2 be their respective heads),
因此,列表已拆分为list1和list2 ( store1和store2是它们各自的头),
Now, we need to reverse the list2. It's pretty much similar as we did in reverse a single linked list.
现在,我们需要反转list2 。 这与我们反向链接单个链表非常相似。
Pre-requisites:
先决条件:
*prev - to store the previous node which will become ultimately the next node after reversal for current node.
* prev-存储前一个节点,该节点在反转当前节点后最终将成为下一个节点。
*cur - to store the current node.
* cur-存储当前节点。
*next - to store the next node which will become current node in the next iteration.
* next-存储将在下一次迭代中成为当前节点的下一个节点。
Initialize *prev & *next to NULL, *cur to head.
初始化* prev和* next为NULL, * cur为首。
while(cur!=NULL)
Set *nextto cur->next
Set cur->nextto *prev
Set *prev to *cur
Set *cur to *next
End While loop
Set head to *prev
3. Appending list1 to reversed list2 //if list2 exists
3.将list1追加到反向list2 // //如果list2存在
Traverse list1 and append list2 at the end.
遍历list1并在末尾附加list2。
IF(store2) //list2 exists
store2=reverse(store2); //reverse list2
*head=store2; //now head is the head to the output list
While(store2->next){ //traverse reversed list2
store2=store2->next;
END While
//append list1(list1 can be NULL also if no such list1 created)
store2->next=store1;
Else //if list2 doesn’t exist
*head=store1; //list1 will be the result
END IF-ELSE
Example with explanation:
带有说明的示例:
Input:
1 -> 2 -> -3 -> 4 -> -5
After splitting:
List1: 1 -> 2 -> 4 -> NULL
List2: -3 -> -5-> NULL
Reversing list2:
- 5-> -3 -> NULL
Appending list1:
-5 -> -3 -> 1 -> 2 -> 4 -> NULL
For example2, List2 doesn't exist.
Output will be only list1
C++ implementation:
C ++实现:
#include<bits/stdc++.h>
using namespace std;
class Node{
public:
int data; // data field
Node *next;
};
void display(Node* head){
Node* current=head; // current node set to head
while(current!=NULL){ //traverse until current node isn't NULL
printf("%d ",current->data);
current=current->next; // go to next node
}
}
Node* creatnode(int d){
Node* temp=(Node*)malloc(sizeof(Node));
temp->data=d;
temp->next=NULL;
return temp;
}
Node* reverse(Node* head){
Node* next=NULL,*prev=NULL,*current;
current=head;
while(current!=NULL){
next=current->next;
current->next=prev;
prev=current;
current=next;
}
return prev;
}
void sortList(Node** head)
{
Node* temp=*head;
//base case
if(!temp || !temp->next)
return ;
Node* posi=NULL,*nega=NULL;
Node* store1=NULL,*store2=NULL;
int countp=0,countn=0;
//absolute sorting
while(temp){
if(temp->data>=0 && countp==0){
posi=temp;
store1=posi;
countp++;
temp=temp->next;
}
else if(temp->data>=0){
posi->next=temp;
posi=posi->next;
temp=temp->next;
}
else if(temp->data<0 && countn==0){
nega=temp;
store2=nega;
countn++;
temp=temp->next;
}
else if(temp->data<0){
nega->next=temp;
nega=nega->next;
temp=temp->next;
}
}
if(posi)
posi->next=NULL;
if(nega)
nega->next=NULL;
if(store2){
store2=reverse(store2);
*head=store2;
while(store2->next){
store2=store2->next;
}
store2->next=store1;
}
else
*head=store1;
}
int main(){
printf("creating the linked list by inserting new nodes at the end\n");
printf("enter 0 to stop building the list, else enter any integer\n");
int k,count=1,x;
Node* curr,*temp;
scanf("%d",&k);
Node* head=creatnode(k); //buliding list, first node
scanf("%d",&k);
temp=head;
///inserting at the end//
while(k){
curr=creatnode(k);
temp->next=curr;//appending each node
temp=temp->next;
scanf("%d",&k);
}
cout<<"before absolute value sorting...\n";
display(head); // displaying the list
cout<<"\nafter absolute sorting...\n";
sortList(&head);
display(head);
return 0;
}
Output
输出量
First run:
creating the linked list by inserting new nodes at the end
enter 0 to stop building the list, else enter any integer
1 2 -3 4 -5 0
before absolute value sorting...
1 2 -3 4 -5
after absolute sorting...
-5 -3 1 2 4
Second run:
creating the linked list by inserting new nodes at the end
enter 0 to stop building the list, else enter any integer
1 2 3 4 5 6 0
before absolute value sorting...
1 2 3 4 5 6
after absolute sorting...
1 2 3 4 5 6
翻译自: https://www.includehelp.com/icp/absolute-sorting-on-a-single-linked-list.aspx
对单个字符串排序