请耐心等待我,我是stackoverflow的新手,所以让我试着解释一下我的问题,如果在我的问题中有任何可以改进的地方,请务必发表评论并且我&# 39;编辑问题
好的,所以我自己有一个链接列表,我想通过列表中的值来订购,这恰好是价格:
tmpPtr->item->price;
我所遇到的问题是切换位置,这里是代码:
struct inventory *sort_list() {
struct inventory *tmpPtr = pFirstNode;
struct inventory *temp = NULL;
struct inventory *tmpNxt = pFirstNode->next;
int tmp;
while(tmpNxt != NULL){
while(tmpNxt != tmpPtr){
if(tmpNxt->item->price < tmpPtr->item->price){
// if next item price is smaller than current
// temp for the next item
// heres the problem....
temp = tmpNxt->next;
tmpNxt->next = tmpPtr;
tmpPtr->next = temp;
}
else{
// if not any smaller continue
tmpPtr = tmpPtr->next;
}
}
tmpPtr = pFirstNode;
tmpNxt = tmpNxt->next;
}
return tmpPtr;
}
这些值不是我从逻辑中预期的排序,任何指针都会很棒 编辑:
struct inventory *sort_list() {
struct inventory *tmpPtr = pFirstNode;
struct inventory *temp = NULL;
struct inventory *tmpNxt = pFirstNode->next;
while(tmpNxt != NULL){
while(tmpNxt != tmpPtr){
if(tmpNxt->item->price < tmpPtr->item->price){
// if next item price is smaller than current
// temp for the next item
if(tmpPtr == pFirstNode){
tmpPtr = pFirstNode->next; // tmpPtr is now second node
pFirstNode->next = tmpPtr->next;
tmpPtr->next = pFirstNode;
pFirstNode = tmpPtr;
}
tmpNxt = tmpPtr->next;
tmpPtr->next = tmpNxt->next;
tmpNxt->next = tmpPtr;
temp->next = tmpNxt;
}
}
temp = tmpPtr;
}
return tmpPtr; // Place holder
}
答案 0 :(得分:1)
当你处于内部if状态时,你有以下状态:
Node1 -> tmpPtr -> tmpNxt -> Node2
您想要达到的目标是:
Node1 -> tmpNxt -> tmpPtr -> Node2
然后你有以下代码:
temp = tmpNxt->next;
//制作temp = Node2
tmpNxt->next = tmpPtr;
//将列表更改为Node1 -> tmpPtr <-> tmpNxt
,tmpPtr->next = temp;
//将列表更改为Node1 ->tmpPtr
和tmpNxt -> tmpPtr -> Node2
正如您所看到的,您错过了Node1 -> tmpNext
的链接。你可以这样做并检查你的结果。
答案 1 :(得分:1)
要交换两个相邻的单链表成员,你需要三个相邻的成员(你要交换的两个成员后面的成员),除非其中一个是列表的头部。
列表案例的负责人→交换list_head
和list_head->next
assert(list_head->next);
next = list_head->next;
list_head->next = next->next;
next->next = list_head;
list_head = next;
其他情况→交换cur
和cur->next
assert(prev->next == cur && cur->next);
next = cur->next;
cur->next = next->next;
next->next = cur;
prev->next = next;
但是,如果将前一个节点重新定义为上一个节点的下一个成员的地址,则可以将这两种情况折叠为单个案例。
void swap_cur_with_next (node **pnext, node *cur) {
assert(*pnext == cur && cur->next);
node *next = cur->next;
cur->next = next->next;
next->next = cur;
*pnext = next;
}
/* swap list_head with list_head->next */
swap_cur_with_next(&list_head, list_head);
/* swap cur with cur->next */
swap_cur_with_next(&prev->next, cur);
使用正确的交换例程,可以更轻松地在列表中实现冒泡排序算法。代码结构可能如下所示:
void bubble_up(node **pnext, node *cur) {
while (cur->next) {
if (need_to_swap(cur)) {
swap_cur_with_next(pnext, cur);
}
pnext = &(*pnext)->next;
cur = *pnext;
}
}
node **pnext = &list_head;
while (*pnext) {
bubble_up(pnext, *pnext);
pnext = &(*pnext)->next;
}
但是,正如另一个答案所述,合并排序是一种更自然,更有效的算法,可用于对列表进行排序。
至少,您可以将节点指针打包到一个数组中,并使用qsort()
对节点指针进行排序,然后按排序顺序将它们链接起来。