C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++でのリストの並べ替え


l1-> l2-> l3->l4->…->l(n-1)->lnのようなリンクリストがあるとします。このリストをl1->ln->l2-> l(n-1)->…などの形式に再配置する必要があります。ここでの制約は、リストノードの値を変更することはできず、ノード自体のみを変更できるということです。したがって、たとえば、リストが[1,2,3,4,5]のような場合、出力は[1,5,2,4,3]

になります。

これを解決するには、次の手順に従います-

  • リバース操作を実行するには、reverseというメソッドを定義します。これは、ノードヘッドとノードprevを取ります。これは以下のように動作します-

  • headがnullの場合は、prevを返します

  • temp:=次の頭

  • 頭の次:=prev、およびprev:=head

  • return reverse(temp、prev)

  • 並べ替えタスクは次のようになります-

  • headがnullの場合、nullを返します

  • 低速と高速と呼ばれる2つのノードポインタを定義し、それらをheadで初期化します

  • 高速と高速の次は両方ともnullではありませんが

    • 遅い:=次の遅い

    • fast:=next of next of fast

  • 速い:=逆(遅いの次)

  • 次のslowをnullに設定し、slow:=head

  • 2つのリストノードポインタtemp1とtemp2を定義します

  • fastはnullではありません

    • temp1:=次の遅い、temp2:=次の速い

    • 次の遅い:=速い、次の速い:=temp1

    • 遅い:=temp1、速い:=temp2

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;
class ListNode{
   public:
   int val;
   ListNode *next;
   ListNode(int data){
      val = data;
      next = NULL;
   }
};
ListNode *make_list(vector<int> v){
   ListNode *head = new ListNode(v[0]);
   for(int i = 1; i<v.size(); i++){
      ListNode *ptr = head;
      while(ptr->next != NULL){
         ptr = ptr->next;
      }
      ptr->next = new ListNode(v[i]);
   }
   return head;
}
void print_list(ListNode *head){
   ListNode *ptr = head;
   cout << "[";
   while(ptr){
      cout << ptr->val << ", ";
      ptr = ptr->next;
   }
   cout << "]" << endl;
}
class Solution {
   public:
   ListNode* successor = NULL;
   ListNode* reverse(ListNode* head, ListNode* prev = NULL){
      if(!head)return prev;
      ListNode* temp = head->next;
      head->next = prev;
      prev = head;
      return reverse(temp, prev);
   }
   void reorderList(ListNode* head) {
      if(!head)return;
      ListNode* slow = head;
      ListNode* fast = head;
      while(fast && fast->next){
         slow = slow->next;
         fast = fast->next->next;
      }
      fast = reverse(slow->next);
      slow->next = NULL;
      slow = head;
      ListNode *temp1, *temp2;
      while(fast){
         temp1 = slow->next;
         temp2 = fast->next;
         slow->next = fast;
         fast->next = temp1;
         slow = temp1;
         fast = temp2;
      }
   }
};
main(){
   vector<int> v = {1,2,3,4,5};
   ListNode *h1 = make_list(v);
   Solution ob;
   (ob.reorderList(h1));
   print_list(h1);
}

入力

[1,2,3,4,5]

出力

[1, 5, 2, 4, 3, ]

  1. C++の次の大きな要素

    次に大きい要素は、その次の最初の大きい要素です。例を見てみましょう。 arr =[4、5、3、2、1] 4の次に大きい要素は5であり、要素3、2、1の次に大きい要素は-1です。これは、それらの後に大きい要素がないためです。 アルゴリズム 乱数で配列を初期化します。 スタックを初期化します。 スタックに最初の要素を追加します。 配列の要素を繰り返し処理します。 スタックが空の場合は、現在の要素をスタックに追加します。 現在の要素がスタックの最上位の要素よりも大きい間。 一番上の要素を、次に大きい要素を現在の要素として印刷します。 一番上の要素

  2. C++でランダムポインタを使用してリストをコピーする

    リンクリストは線形データ構造であり、各ノードには2つのブロックがあり、一方のブロックにはノードの値またはデータが含まれ、もう一方のブロックには次のフィールドのアドレスが含まれます。 各ノードにリスト内の他のノードを指すランダムポインタが含まれるようなリンクリストがあると仮定します。タスクは、元のリストと同じリストを作成することです。ランダムなポインタを持つ元のリストからリストをコピーすることを、リンクリストの「ディープコピー」と呼びます。 例 入力-1 出力: 5-> 2 -> 3 -> 7 ->4 -> 説明: この問題を解決するためのア