※「セキュリティ保護のため...」というメッセージが出る方・日本語が入力できない方へ
←↑→ (4)クイックソート


  昔からなぜか人気のあるソートである。データを「適当に」決めた基準値
  を元に大きい物と小さい物とに2分割し、その分割されたものを更に2分
  割する、ということを繰り返してソートする。

 コーディングが単純で実装しやすいが、重大な欠陥がある。それについて
 は実行時間の掲示後に書く。

【Coding Sample】(Quick Sort)

void CSortDlg::QuickSort()
{
	QuickSort(0, m_dcnt-1);
}
void CSortDlg::QuickSort(long n1, long n2)
{
	long i,j;
	long m,x;

	if (n2<=n1)
		return;

	m = m_data[n1];
	i = n1+1;
	j = n2;
	while(i<j)
	{
		if (m_data[i]<m)
		{
			if (m<=m_data[j])	// i<m<j : iは小、jは大
			{
				i++;
				j--;
			}
			else	//i,j<m : 両方とも小
			{
				x = m_data[i+1];
				m_data[i+1] = m_data[j];
				m_data[j] = x;
				i+=2;
			}
		}
		else
		{
			if (m<=m_data[j])	// m<i,j : i,jともに大
			{
				x = m_data[j-1];
				m_data[j-1] = m_data[i];
				m_data[i] = x;
				j-=2;
			}
			else	// j<m<i : jは小,iは大
			{
				x = m_data[j];
				m_data[j] = m_data[i];
				m_data[i] = x;
				i++;
				j--;
			}
		}
	}
	if (i==j)
	{
		if (m<=m_data[i])
			j--;
		else
			i++;
	}
	//ここで n1+1〜jはm未満, i〜n2はm以上になっている (j+1=i)

	if (j==n1)	//全てm以上だった
	{
		QuickSort(i,n2);
	}
	else	//m未満のものがある
	{
		x = m_data[j];
		m_data[j] = m_data[n1];
		m_data[n1] = x;

		QuickSort(n1,j-1);
		QuickSort(i,n2);
	}
	
}


【実行時間】(Pentium-75MHz VisualC++5.0 Release Mode)

               件数    乱順    正順    逆順

QuickSort(r)      100    0.00000     0.00000     0.00000
QuickSort(r)     1000    0.00000     0.00000     0.00000
QuickSort(r)    10000    0.00000     0.16000     1.71000
QuickSort(r)    30000    0.11000     0.93000    10.98000
QuickSort(r)   100000    0.33000     4.94000    64.70000
QuickSort(r)   300000    1.04000    31.52000   684.32000
QuickSort(r)  1000000    4.72000   209.98000    -------
QuickSort(r)  3000000   24.12000    -------     -------

 QuickSortはご覧の通り、順序に並んだデータに極端に弱い。つまり、正順
 ・逆順などに並んだデータにおいては分割が「1個とその他」にしか分かれ
 てくれないので、王様探し並みに速度が落ちてしまうのである。

 また、このソートは他のソートと違って、First in First out ではないの
 で、入力順を保ちたければ、入力順もキーに加えておく必要がある。


←↑→
(C)copyright ffortune.net 1995-2007 produced by ffortune and Lumi.
お問い合わせはこちらから