[英]How would I modify this singly linked list sorting algorithm so that it sorts by ascending order properly?
I am currently trying to sort a singly linked list in descending order.我目前正在尝试按降序对单链表进行排序。 Realizing there is no straightforward way to do that with only a next pointer, I opted for the approach of sorting the list in ascending order first, then reversing the list, so that the items are sorted in descending order.
意识到仅使用 next 指针没有直接的方法来做到这一点,我选择了先按升序对列表进行排序,然后将列表反转,以便项目按降序排序的方法。
Edit 1: I'm trying to ensure that the items are stored in descending order based on how frequently they are accessed in the linked list.编辑1:我试图确保项目根据它们在链接列表中的访问频率以降序存储。 The printing is just to help me check the order of the linked list.
打印只是为了帮助我检查链表的顺序。
Edit 2: Minimum Working Example as Requested:编辑 2:要求的最小工作示例:
main.c main.c
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node_struct {
char *name;
int accessCount;
struct node_struct *next;
}Knowledge_Node;
int knowledge_put();
int knowledge_get();
void printList();
void sortList();
void reverseList();
Knowledge_Node *head = NULL;
int main(int argc, char*argv[]){
// Putting James into the linked list
knowledge_put("James");
//Get the James node twice
knowledge_get("James");
knowledge_get("James");
//Add Carrie to the linked list
knowledge_put("Carrie");
//Get the Carrie node thrice
knowledge_get("Carrie");
knowledge_get("Carrie");
knowledge_get("Carrie");
// Add adams to linked list
knowledge_put("Adams");
knowledge_get("Adams");
printList();
}
Add Node Function添加节点 Function
int knowledge_put(char * name) {
Knowledge_Node *node = (Knowledge_Node *)malloc(sizeof(Knowledge_Node));
if (node == NULL) {
return -3;
}
node->name = (char *)malloc(sizeof(char) * 255);
if (node->name == NULL){
return -3;
}
strncpy(node->name, name, strlen(name) + 1);
node->accessCount = 0;
node->next = head;
head = node;
sortList();
}
Retrieve Node Function检索节点 Function
int knowledge_get(char * name){
Knowledge_Node *search = head;
while (search != NULL){
if (strcmp(search->name, name) == 0){
search->accessCount = search->accessCount + 1;
sortList();
return 0;
}
search = search->next;
}
return -1;
}
Sort List Function:排序列表 Function:
void sortList(){
Knowledge_Node *temp = head;
Knowledge_Node *backPtr = head;
Knowledge_Node *prevNode = NULL;
while (temp != NULL){
Knowledge_Node *nextNode = temp->next;
//currentNode is assigned to temp, which is the pointer used to iterate through the list
Knowledge_Node *currentNode = temp;
//Doing a simple check to see if nextNode has something
if (nextNode != NULL) {
if(nextNode != NULL){
if (currentNode->accessCount > nextNode->accessCount) {
//If previousNode is NULL it means currentNode is the head of //the linked list
//There's different logic to handle each case
if (prevNode != NULL){
prevNode->next = nextNode;
nextNode->next = currentNode;
currentNode->next = NULL;
} else if (prevNode == NULL){
currentNode->next = nextNode->next;
nextNode->next = currentNode;
head = nextNode;
}
}
}
}
//Assigning of previousNode. We'll need this for the linking/un-linking //process
prevNode = currentNode;
temp = temp->next;
}
reverseList();
}
Reverse List Function:反向列表 Function:
void reverseList(){
//Initialise three pointers, which we'll use to reverse the links of the
//linked list
Knowledge_Node *prevNode = NULL;
Knowledge_Node *currentNode = head;
Knowledge_Node *nextNode = NULL;
//This is where the linked list reversal is done
while (currentNode != NULL){
nextNode = currentNode->next;
currentNode->next = prevNode;
prevNode = currentNode;
currentNode = nextNode;
}
//Previous Node points to the last node in the original list, so let's
//make it the new head
head = prevNode;
}
Print List Function:打印清单 Function:
void printList() {
Knowledge_Node *temp = head;
while (temp != NULL){
printf("%s %d\n", temp->name, temp->accessCount);
temp = temp->next;
}
}
Expected Output:预期 Output:
Carrie 3
James 2
Adams 1
Actual Output:实际 Output:
Adams 1
Carrie 3
James 2
The ascending sort seems to work fine on its own, without the reverse sort.升序排序本身似乎工作正常,没有反向排序。
Hopefully someone can guide me based on this as to how I can change the sortList algorithm to make it sort in ascending, then descending order properly希望有人可以根据此指导我如何更改 sortList 算法以使其按升序排序,然后正确降序排序
Removed rest of content to keep things brief删除了 rest 的内容以保持简短
I figured out what is wrong with your sorting algorithm.我弄清楚你的排序算法有什么问题。 Since your linked list is a singly linked list you can't use a more efficient sorting algorithm like insert sort.
由于您的链表是单链表,因此您不能使用更有效的排序算法,如插入排序。 So I used bubble sort in this matter.
所以我在这件事上使用了冒泡排序。 In your algorithm you have only used a one loop.
在您的算法中,您只使用了一个循环。 You must use nested two loops.
您必须使用嵌套的两个循环。 See details about bubble sort .
请参阅冒泡排序的详细信息。
Also instead of keeping the head pointer for the list as the newly added node, you can define a structure called List
and have the head pointer in that.此外,您可以定义一个名为
List
的结构并在其中包含头指针,而不是将列表的头指针保留为新添加的节点。 It's more clear.更清楚了。
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node_struct {
char *name;
int accessCount;
struct node_struct *next;
}Knowledge_Node;
typedef struct list{
Knowledge_Node* head;
int count;
}List;
int knowledge_put();
int knowledge_get();
void printList();
void sortList();
void reverseList();
List* list1=NULL;
int main(int argc, char*argv[]){
list1= (List*)malloc(sizeof(List)*1);
list1->head=NULL;
list1->count=0;
// Putting James into the linked list
knowledge_put("James");
//Get the James node twice
knowledge_get("James");
knowledge_get("James");
//Add Carrie to the linked list
knowledge_put("Carrie");
//Get the Carrie node thrice
knowledge_get("Carrie");
knowledge_get("Carrie");
knowledge_get("Carrie");
// Add adams to linked list
knowledge_put("Adams");
knowledge_get("Adams");
sortList();
reverseList();
printList();
}
int knowledge_put(char * name) {
Knowledge_Node *node = (Knowledge_Node *)malloc(sizeof(Knowledge_Node));
if (node == NULL) {
return -3;
}
node->name = (char *)malloc(sizeof(char) * 255);
if (node->name == NULL){
return -3;
}
strncpy(node->name, name, strlen(name) + 1);
node->accessCount = 0;
node->next = list1->head;
list1->head = node;
list1->count++;
return -3;
}
int knowledge_get(char * name){
Knowledge_Node *search = list1->head;
while (search != NULL){
if (strcmp(search->name, name) == 0){
search->accessCount = search->accessCount + 1;
return 0;
}
search = search->next;
}
return -1;
}
void sortList(){
Knowledge_Node* sort=list1->head;
Knowledge_Node* nextl=list1->head->next;
Knowledge_Node* temp=(Knowledge_Node *)malloc(sizeof(Knowledge_Node));
temp->name = (char *)malloc(sizeof(char) * 255);
//const Knowledge_Node* c_sort=list1->head;
for(int i=0;i<list1->count-1;i++){
while(nextl!=NULL&&sort!=NULL){
if(sort->accessCount > nextl->accessCount){
temp->accessCount=sort->accessCount;
strncpy(temp->name,sort->name,strlen(sort->name)+1);
sort->accessCount=nextl->accessCount;
strncpy(sort->name,nextl->name,strlen(nextl->name)+1);
nextl->accessCount=temp->accessCount;
strncpy(nextl->name,temp->name,strlen(temp->name)+1);
}
sort=sort->next;
nextl=nextl->next;
}
sort=list1->head;
nextl=list1->head->next;
}
}
void reverseList(){
//Initialise three pointers, which we'll use to reverse the links of the
//linked list
Knowledge_Node *prevNode = NULL;
Knowledge_Node *currentNode = list1->head;
Knowledge_Node *nextNode = NULL;
//This is where the linked list reversal is done
while (currentNode != NULL){
nextNode = currentNode->next;
currentNode->next = prevNode;
prevNode = currentNode;
currentNode = nextNode;
}
//Previous Node points to the last node in the original list, so let's
//make it the new head
list1->head = prevNode;
}
void printList() {
Knowledge_Node *temp = list1->head;
while (temp != NULL){
printf("%s %d\n", temp->name, temp->accessCount);
temp = temp->next;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.