【发布时间】:2020-04-04 01:07:07
【问题描述】:
我目前正在尝试按降序对单链表进行排序。意识到只有一个 next 指针没有直接的方法来做到这一点,我选择了先按升序对列表进行排序,然后将列表反转,以便项目按降序排序的方法。
编辑 1: 我试图确保项目根据它们在链接列表中的访问频率以降序存储。打印只是为了帮助我检查链表的顺序。
编辑 2: 要求的最低工作示例:
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();
}
添加节点功能
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();
}
检索节点函数
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;
}
排序列表功能:
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();
}
反向列表功能:
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;
}
打印列表功能:
void printList() {
Knowledge_Node *temp = head;
while (temp != NULL){
printf("%s %d\n", temp->name, temp->accessCount);
temp = temp->next;
}
}
预期输出:
Carrie 3
James 2
Adams 1
实际输出:
Adams 1
Carrie 3
James 2
没有反向排序,升序排序似乎可以正常工作。
希望有人可以基于此指导我如何更改 sortList 算法以使其按升序排序,然后正确降序排序
删除了其余内容以保持简短
【问题讨论】:
-
你的“反向打印”函数可以递归吗?如果是这样,您可以对 升序 进行排序并仅以相反的顺序打印列表 [无需 创建 反向列表]。也许您应该发布您的反向/打印功能。发布您的整个代码可能会有所帮助。它应该干净地编译并且可以下载。另外,发布您的示例数据 [在代码块中]
-
@CraigEstey 我添加了一个最小工作示例来演示我想要做什么,也许你可以帮忙看看?
-
@luckyteos 您的代码需要更正什么?
-
@NemindaPrabhashwara 反向排序无法正常工作,这可能是由于升序排序不正确造成的。例如,3,2,1 应该排序为 1,2,3,但目前我得到的是 2,3,1。寻找一些帮助来改变算法的行为,使其正确排序
-
@luckyteos 错误出在您的排序算法中,而不是在反向函数中。