Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 尝试仅通过重新排列指针对链表进行冒泡排序。我的代码有一个2节点列表的变通方法,我想去掉它_C_Sorting_Pointers - Fatal编程技术网

C 尝试仅通过重新排列指针对链表进行冒泡排序。我的代码有一个2节点列表的变通方法,我想去掉它

C 尝试仅通过重新排列指针对链表进行冒泡排序。我的代码有一个2节点列表的变通方法,我想去掉它,c,sorting,pointers,C,Sorting,Pointers,我的排序函数可以工作,但我必须为列表中只有两个节点的情况制定一个变通方法。我想知道是否有人能帮我修复我的排序算法,这样它就可以处理包括这一个在内的所有情况。函数接受一个指向节点(列表的头部)的指针,然后返回一个指向节点(新头部)的指针。节点包含5个字符的C字符串,包括空终止字符和名为next的指针 Node *sortList(Node *head) { Node *prevNode, *currNode, *tempNode; int wordCount = 1; in

我的排序函数可以工作,但我必须为列表中只有两个节点的情况制定一个变通方法。我想知道是否有人能帮我修复我的排序算法,这样它就可以处理包括这一个在内的所有情况。函数接受一个指向节点(列表的头部)的指针,然后返回一个指向节点(新头部)的指针。节点包含5个字符的C字符串,包括空终止字符和名为
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