リンクされたリストを分割する
所属コラム:データ構造の質問タイプで遊ぶ
ブロガーのホームページ: Chuyang785
コードホスティング: chuyang785
ご支援ありがとうございます。あなたの「いいね!」と注目が私にとって最大のサポートです。!!
ブロガーもより良いブログ記事を作成するためにさらに努力します。!
ついてきて、ついてきて、ついてきて、大事なことは三回言ってください!!!!!!!!
1. 話題のソース
2. トピックの説明
リンク リストのヘッド ノード head と特定の値 x が与えられた場合、x 未満のすべてのノードが x 以上のノードの前に表示されるようにリンク リストを分割してください。
各パーティション内のノードの初期相対位置を保持する必要はありません。
3. 問題解決のアイデア
この質問の意味は、x 未満のデータを左側に、x 以上のデータを右側に配置するというもので、順序を変更しても元の順序は変わりません。
私たちのアイデアは、2 つのリンク リストを作成し、1 つのリンク リスト LessHead は x 未満のデータを格納し、もう 1 つのリンク リスト GreaterHead は x 以上のデータを拡大し、最後に 2 つの側を 1 つのリンク リストにマージしてから、新しいリンクリストの最初のノードのアドレス。
リンクを容易にするために、リンクされた 2 つのリストのヘッド ノードとして、val が無効なデータであるが、next が次のアドレスを指すセンチネルを作成する方法を使用します。
次に、リンク リストを横断するための変数 cur を作成し、サイズに応じてそれらを異なるリンク リストに割り当てます。
図:
x=3 のとき、cur はトラバースを開始します。まず、最初のノードのデータは 1 であり、3 より小さいです。それを LessHead リンク リストにリンクし、LessNext を使用してリンクされたノードを記録します。 Diandian は、将来リンクするときに LessHead で表すだけで済み、リンクが完了した後にリンク先リストの先頭ノードのアドレスを返すときに、直接 LessHead に戻れるという利点があります。
同じ cur が最初のノードを通過した後、2 番目のノードにアクセスするには cur=cur->next にするだけで済みます。これは、最初のノードをチャネルにリンクしたときに 2 番目のノードを指す最初のノードを破棄しなかったためです。ノードであっても、最初のノードを通じて 2 番目のノードを見つけることができます。同様に、greaterNext を使用して次のノードのアドレスを表します。
類推すると、cur が NULL を指すとループが停止します。
次のステップでは、2 つのリンクされたリストをマージします。
行にlessTail->next=greaterHead->next;を設定するだけです。
しかし、ここで特に重要なことは、接続した後、greaterNext がどこを指すのかということです。それは本当に NULL を指しているのでしょうか? 答えは否定的です。
前のリンクに戻りましょう。5
つのデータを保存する次のリンクが 2 のアドレスを指していることがわかります。
画像解析はこんな感じになるのですが、このままではループになってしまい、アドレスを返す際にメモリの問題が発生してしまいます。
したがって、ここでの解決策は、greaterNext->next を空にすること、つまり、greaterNext->next=NULL にすることです。
4. コード表示
struct ListNode* partition(struct ListNode* head, int x)
{
//创建哨兵位,方便链接
struct ListNode* lessHead,*lessTail,*greaterHead,*greaterTail;
//存放小于x的数据
lessHead=lessTail=(struct ListNode*)malloc(sizeof(struct ListNode));
lessHead->next=NULL;
//存放大于等于x的数据
greaterHead=greaterTail=(struct ListNode*)malloc(sizeof(struct ListNode));
greaterHead->next=NULL;
//遍历链表指针
struct ListNode* cur=head;
while(cur)
{
//尾插
if(cur->val < x)
{
lessTail->next=cur;
lessTail=cur;
}
else
{
greaterTail->next=cur;
greaterTail=cur;
}
cur=cur->next;
}
//链接两个链表
lessTail->next=greaterHead->next;
//消除环,我们的5最后还指向我们2,这个时候就形成了一个环、
greaterTail->next=NULL;
struct ListNode* newnode=lessHead->next;
//最后释放两个创建的内存空间
free(lessHead);
free(greaterHead);
return newnode;
}