追加のリソースを使用せずにキューを並べ替える

最近、次の問題が発生しました。「2つのキューを結合して、合計キューがソートされるようにします。」 ソートの要件は次のとおりです。アルゴリズムがどれほど遅くても、1つの変数を除き、中間オブジェクトを使用しないでください。 キューソートアルゴリズムを作成する最初の試みは、無限ループから抜け出す方法の問題につながりましたが、最終的には必要なアルゴリズムを取得しました。



最初に、キューの実装を定義しましょう。標準リストを使用してPythonでそれを行います。



class EmptyQueueError(Exception): @staticmethod def message(): return 'queue is empty!' class FullQueueError(Exception): @staticmethod def message(): return 'queue is full!' class Queue: def __init__(self, max_size=None): self.__queue = [] self.__max_size = max_size def get_size(self): return len(self.__queue) def get_list(self): return self.__queue def push(self, item): if len(self.__queue) != self.__max_size or self.__max_size is None: self.__queue.append(item) else: raise FullQueueError def pop(self): if len(self.__queue): item = self.__queue[0] del self.__queue[0] return item else: raise EmptyQueueError def get_head(self): if len(self.__queue): return self.__queue[0] else: raise EmptyQueueError
      
      





メソッドのセットが最も標準的です。 キューは固定サイズにすることができ、コンストラクターでサイズを決定する数値パラメーターを渡す必要があります。そうでない場合、キューは無限になります。 get_list()メソッドは内部リストへのリンクを返すため安全ではなく、外部から変更することは完全に推奨されていません。 ただし、デバッグには便利です。



EmptyQueueErrorおよびFullEmptyError例外クラスは、それぞれキューの空/完全性を制御します。



それでは、楽しみの部分に移りましょう。キューの並べ替えです。 並べ替えは、最小のアイテムから最大のアイテムへと行われます。 1つの変数を使用して、キューからアイテムを一時的に保存できます。 また、 自由にget_head()メソッドを使用できます。このメソッドは、キューの先頭から単純に要素を返します。 ソートアルゴリズムの基本は、 pop()メソッドを使用してtemp変数に次の要素を配置することです。 さらにループ内で、キューの先頭をこのtempと比較し、先頭の要素が大きい場合は、キューの最後にtempを配置し、先頭から次の要素を割り当てます( pop() )。 head要素がそれ以上ない場合は、末尾に配置し、 tempには触れません。つまり、キューを1つの要素に「巻き戻し」ます。



しかし、問題は、サイクルをいつ停止する必要があるかです。



アルゴリズムが最大値を見つけたら、キューを完全にスクロールして、キューにそれ以上の値がないことを確認する必要があります。 これは、キュー内の要素と同じ回数だけワインディングを実行する必要があることを意味します。 これを行うには、カウンター変数が必要です( ステップ )。 スクロール後、安全に一時キューをプッシュして操作を繰り返すことができます。



また、キューで新しい最大値を見つける場合、スクロールカウンターを0にリセットします。



そのため、最初にsteps = 0を設定し、次の最大値が見つからない場合は1ずつ増やします。



ただし、このサイクルの実行後、キューはほとんどソートされないため、キュー内の要素が1つもない場合、つまりqueue_lengthが1である回数だけ操作を繰り返す必要があります



 def my_sorting(queue): for i in range(queue.get_size() - 1): temp = queue.pop() steps = 0 while steps < queue.get_size(): print(temp, queue.get_list()) if temp < queue.get_head(): queue.push(temp) temp = queue.pop() steps = 0 else: queue.push(queue.pop()) steps += 1 queue.push(temp) print(queue.get_list()) return queue
      
      





結果:追加のリソースを使用せずにキューがソートされます。



All Articles