関数が未定義の動作をしています。
与えられたデータに対応するノードを見つけるもう1つの関数を書くとよいでしょう。
それにもかかわらず、関数swapNodes
は次のように書くことができます。スワップされるノードを見つけ、ノードとそのデータメンバへのポインタをスワップしますnext
。
ここでは、ここで
void swap(struct Node **first, struct Node **second)
{
struct Node *tmp = *first;
*first = *second;
*second = tmp;
}
void swapNodes(struct Node **headr, int key1, int key2)
{
if (key1 == key2) return;
struct Node **first = headr;
while (*first && (*first)->data != key1) first = &(*first)->next;
if (*first == NULL) return;
struct Node **second = headr;
while (*second && (*second)->data != key2) second = &(*second)->next;
if (*second == NULL) return;
swap(first, second);
swap(&(*first)->next, &(*second)->next);
}
あるが実証プログラムです。
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *node)
{
while(node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
void swap(struct Node **first, struct Node **second)
{
struct Node *tmp = *first;
*first = *second;
*second = tmp;
}
void swapNodes(struct Node **headr, int key1, int key2)
{
if (key1 == key2) return;
struct Node **first = headr;
while (*first && (*first)->data != key1) first = &(*first)->next;
if (*first == NULL) return;
struct Node **second = headr;
while (*second && (*second)->data != key2) second = &(*second)->next;
if (*second == NULL) return;
swap(first, second);
swap(&(*first)->next, &(*second)->next);
}
int main(void)
{
struct Node *start = NULL;
push(&start, 7);
push(&start, 6);
push(&start, 5);
push(&start, 4);
push(&start, 3);
push(&start, 2);
push(&start, 1);
printf("\n Linked list before calling swapNodes() ");
printList(start);
swapNodes(&start, 4, 3);
printf("\n Linked list after calling swapNodes() ");
printList(start);
return 0;
}
その出力は、実際にそれが(与えられたデータのためのノードを見つけ別機能なし)が書き込まれるように機能swapNodes
は2つのことを行い
Linked list before calling swapNodes() 1 2 3 4 5 6 7
Linked list after calling swapNodes() 1 2 4 3 5 6 7
である:それは1)は、2つのノードを見つけて2)それらを交換する。ノードの検索が失敗する可能性があります。したがって、関数は、ノードがスワップされたかどうかをユーザーに報告する必要があります。この場合、戻り値の型がint
であると宣言することが望ましいです。例えば
int swapNodes(struct Node **headr, int key1, int key2)
{
int success = key1 != key2;
if (success)
{
struct Node **first = headr;
struct Node **second = headr;
while (*first && (*first)->data != key1) first = &(*first)->next;
success = *first != NULL;
if (success)
{
while (*second && (*second)->data != key2) second = &(*second)->next;
success = *second != NULL;
}
if (success)
{
swap(first, second);
swap(&(*first)->next, &(*second)->next);
}
}
return success;
}
それはノードがより明確かつ簡単になりますスワップ、関数前述したように、ノードを検索する別の関数を書くことができます。
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *node)
{
while(node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
void swap(struct Node **first, struct Node **second)
{
struct Node *tmp = *first;
*first = *second;
*second = tmp;
}
struct Node ** find(struct Node **headr, int data)
{
while (*headr && (*headr)->data != data) headr = &(*headr)->next;
return headr;
}
void swapNodes(struct Node **first, struct Node **second)
{
swap(first, second);
swap(&(*first)->next, &(*second)->next);
}
int main(void)
{
struct Node *start = NULL;
push(&start, 7);
push(&start, 6);
push(&start, 5);
push(&start, 4);
push(&start, 3);
push(&start, 2);
push(&start, 1);
printf("\n Linked list before calling swapNodes() ");
printList(start);
struct Node **first;
struct Node **second;
if ((first = find(&start, 4)) && (second = find(&start, 3))) swapNodes(first, second);
printf("\n Linked list after calling swapNodes() ");
printList(start);
return 0;
}
例えば
は、いくつかのサンプルのテストケースでデバッガ上で実行してみてください。 –
データをスワップすることが許可されている場合は、ポインタ操作によるエラーを避けるためにデータをスワップできます。 –
@ ilz0Rあなたが指摘した参考資料はこの質問には役に立たない。 –