C 尝试仅通过重新排列指针对链表进行冒泡排序。我的代码有一个2节点列表的变通方法,我想去掉它
我的排序函数可以工作,但我必须为列表中只有两个节点的情况制定一个变通方法。我想知道是否有人能帮我修复我的排序算法,这样它就可以处理包括这一个在内的所有情况。函数接受一个指向节点(列表的头部)的指针,然后返回一个指向节点(新头部)的指针。节点包含5个字符的C字符串,包括空终止字符和名为C 尝试仅通过重新排列指针对链表进行冒泡排序。我的代码有一个2节点列表的变通方法,我想去掉它,c,sorting,pointers,C,Sorting,Pointers,我的排序函数可以工作,但我必须为列表中只有两个节点的情况制定一个变通方法。我想知道是否有人能帮我修复我的排序算法,这样它就可以处理包括这一个在内的所有情况。函数接受一个指向节点(列表的头部)的指针,然后返回一个指向节点(新头部)的指针。节点包含5个字符的C字符串,包括空终止字符和名为next的指针 Node *sortList(Node *head) { Node *prevNode, *currNode, *tempNode; int wordCount = 1; in
next
的指针
Node *sortList(Node *head) {
Node *prevNode, *currNode, *tempNode;
int wordCount = 1;
int i;
// make sure the list is not empty
// and has more than one node
if (head == NULL) {
return NULL;
} else
if (head->next == NULL) {
return head;
}
currNode = head;
// find out how many nodes there are
while (currNode->next != NULL) {
wordCount++;
currNode = currNode->next;
}
// workaround for lists with two items
if (wordCount == 2) {
if (strcmp((head->word), (head->next->word)) > 0) {
tempNode = head->next;
head->next->next = head;
head->next = NULL;
head = tempNode;
return head;
} else {
return head;
}
}
// bubble sort
for (i = 1; i < wordCount; i++) {
currNode = prevNode = head;
while (currNode->next != NULL) {
if (strcmp((currNode->word), (currNode->next->word)) > 0) {
tempNode = currNode->next;
currNode->next = currNode->next->next;
tempNode->next = currNode;
if (head == currNode) {
head = prevNode = tempNode;
} else {
prevNode->next = tempNode;
currNode = tempNode;
}
}
prevNode = currNode;
currNode = currNode->next;
}
}
return head;
}
Node*sortList(Node*head){
节点*prevNode、*currNode、*tempNode;
int-wordCount=1;
int i;
//确保列表不是空的
//并且具有多个节点
if(head==NULL){
返回NULL;
}否则
if(head->next==NULL){
回流头;
}
节点=头部;
//找出有多少个节点
while(currNode->next!=NULL){
字数++;
currNode=currNode->next;
}
//具有两个项目的列表的变通方法
如果(字数=2){
如果(strcmp((head->word),(head->next->word))>0){
tempNode=head->next;
头部->下一步->下一步=头部;
head->next=NULL;
head=tempNode;
回流头;
}否则{
回流头;
}
}
//气泡排序
对于(i=1;inext!=NULL){
如果(strcmp((currNode->word),(currNode->next->word))>0){
tempNode=currNode->next;
currNode->next=currNode->next->next;
tempNode->next=currNode;
if(head==currNode){
head=prevNode=tempNode;
}否则{
prevNode->next=tempNode;
currNode=tempNode;
}
}
prevNode=currNode;
currNode=currNode->next;
}
}
回流头;
}
你可以玩一个经典的把戏:拿一个指针头
,然后让它指向上一个节点的下一个成员:
Node *sortList(Node *head) {
// make sure the list is not empty
if (head != NULL) {
// bubble sort
for (;;) {
int swapped = 0;
Node **linkp = &head;
Node *currNode = head;
Node *nextNode;
while ((nextNode = currNode->next) != NULL) {
if (strcmp(currNode->word, nextNode->word) > 0) {
currNode->next = nextNode->next;
nextNode->next = currNode;
*linkp = currNode = nextNode;
swapped++;
}
link = &currNode->next;
currNode = nextNode;
}
if (swapped == 0)
break;
}
}
return head;
}
该算法仍然是Bubblesort,时间复杂度低O(n2)
,但我使用了更好的完成测试:您不再需要计算列表中的元素数量,只需检查扫描阶段是否交换了任何节点就足够了。此算法也适用于单例,因此您不再需要特殊情况。您可以玩一个经典的把戏:取一个指针头
,然后使其指向上一个节点的下一个成员:
Node *sortList(Node *head) {
// make sure the list is not empty
if (head != NULL) {
// bubble sort
for (;;) {
int swapped = 0;
Node **linkp = &head;
Node *currNode = head;
Node *nextNode;
while ((nextNode = currNode->next) != NULL) {
if (strcmp(currNode->word, nextNode->word) > 0) {
currNode->next = nextNode->next;
nextNode->next = currNode;
*linkp = currNode = nextNode;
swapped++;
}
link = &currNode->next;
currNode = nextNode;
}
if (swapped == 0)
break;
}
}
return head;
}
该算法仍然是Bubblesort,时间复杂度低O(n2)
,但我使用了更好的完成测试:您不再需要计算列表中的元素数量,只需检查扫描阶段是否交换了任何节点就足够了。此算法也适用于单例,因此您不需要再考虑任何特殊情况。问题在于:
if (head == currNode) {
head = prevNode = tempNode;
// here
} else {
prevNode->next = tempNode;
currNode = tempNode;
}
在必须交换前两个元素的if
情况下,prevNode
指向新的头部,但currNode
不变,指向下一个元素。然后,当您向上移动prevNode
和currenode
时,您将currenode
两个元素移过头部
。如果列表中只有两个元素,currNode
然后指向NULL
,访问循环顶部的currNode->next
,会导致核心转储
重新分配head
后,添加currNode=tempNode代码>:
if (head == currNode) {
head = prevNode = tempNode;
currNode = tempNode;
} else {
prevNode->next = tempNode;
currNode = tempNode;
}
或者:
if (head == currNode) {
head = prevNode = tempNode;
} else {
prevNode->next = tempNode;
}
currNode = tempNode;
一旦这样做,您就可以摆脱两个元素的特殊情况。问题在于:
if (head == currNode) {
head = prevNode = tempNode;
// here
} else {
prevNode->next = tempNode;
currNode = tempNode;
}
在必须交换前两个元素的if
情况下,prevNode
指向新的头部,但currNode
不变,指向下一个元素。然后,当您向上移动prevNode
和currenode
时,您将currenode
两个元素移过头部
。如果列表中只有两个元素,currNode
然后指向NULL
,访问循环顶部的currNode->next
,会导致核心转储
重新分配head
后,添加currNode=tempNode代码>:
if (head == currNode) {
head = prevNode = tempNode;
currNode = tempNode;
} else {
prevNode->next = tempNode;
currNode = tempNode;
}
或者:
if (head == currNode) {
head = prevNode = tempNode;
} else {
prevNode->next = tempNode;
}
currNode = tempNode;
一旦你这样做了,你就可以摆脱两个元素的特殊情况。我不明白如果函数如你所说的那样工作,为什么你需要一个变通方法?我希望我的变通方法没有必要。我不想有一个特殊的情况,我有一个不同的排序算法。我希望我的算法适用于所有情况。我不明白如果函数如你所说的那样工作,为什么你需要一个变通方法?我希望我的变通方法不是必需的。我不想有一个特殊的情况,我有一个不同的排序算法。我希望我的算法适用于所有情况。非常感谢!我有个问题。使用(;;)比使用while(1)有优势吗?此外,我从来没有想过在语句中增加下一个节点((nextNode=currNode->next)!=NULL){
我必须记住,对于未来的项目,for(;;)
是无限循环的惯用用法。while(1)
不太明显,特别是如果您有一个名为l
的变量,它可能会与混淆,而(l)
(结论:也不要命名变量l
)。非常感谢!我有一个问题。使用(;;)比使用(;)有什么好处吗(1)另外,我从来没有想过在语句中增加next节点,而((nextNode=currNode->next)!=NULL){
我必须记住,对于f