あなたのアルゴリズムは可能な限り最高のものです。多くの場合、単純化することで少しスピードを上げることができます。絵を描いてポインタについて推論する代わりに、入力リストの先頭から要素をポップし、キューの追加操作を使用して結果を作成することを検討してください。擬似コードでは、
set_empty(rtn);
while (head) {
fst = pop(head);
if (head) {
snd = pop(head);
add_at_tail(rtn, snd);
}
add_at_tail(rtn, fst);
}
これif
は、入力リストの長さが奇数の場合から保護するためにのみ必要です。リストの長さが同じであることが確実な場合は、スキップできます。
これで、popの実装は非常に簡単になりました。ダミーのヘッドノードを使用すると、テールへの追加操作が最も簡単になります。したがって、Cでは次のようになります。
node *swap(node *head)
{
node dummy[1]; // set_empty(rtn);
node *rtn = dummy;
while (head) {
node *fst = head; // fst = pop(head);
head = head->next;
if (head) {
node *snd = head; // snd = pop(head);
head = head->next;
rtn->next = snd; // add_to_tail(rtn, snd);
rtn = rtn->next;
}
rtn->next = fst; // add_to_tail(rtn, fst);
rtn = rtn->next;
}
rtn->next = NULL; // terminate tail
return dummy->next;
}
今、私はこのコードをテストしていませんが、おそらくタイプミスか2つを法としてうまく実行されると確信しています。テストはあなたのテストよりも少なくなります(要素ごとに1つだけ)。テストはパイプラインに干渉する可能性があるため、比較的費用がかかるため、私の場合は少し速く実行する必要があります。ほぼ確実に、この違いは関係ありません。
ただし、私のコードは理解しやすいと思います。もちろん、それは偏った意見の1つにすぎませんが、読みやすさはメンテナンス中に重要です。
NB 今、私は簡単なテストを行いました、そしてそれは最初の試みで働きました!一方、私があなたのコードを試したとき、私はでsegvを手に入れました
first->next=(third->next==NULL ? third : third->next);
以下はテストフレームです。何かおかしいと思いますか?
typedef struct node_s {
struct node_s *next;
int val;
} node;
// swap goes here
int main(void)
{
node dummy[1];
node *p = dummy;
for (int i = 0; i < 16; i++) {
p->next = malloc(sizeof(node));
p = p->next;
p->next = NULL;
p->val = 'a' + i;
}
p = swap(dummy->next);
while (p) {
printf("%c ", p->val);
p = p->next;
}
printf("\n");
return 0;
}