こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

解決済みの質問

クイックソートをC++で作りたいのですが・・・

題の通り、C++でクイックソートを作りたいのですが、以下のコードではセグメンテーションエラーで動きませんでした。partition関数があやしいと思い、色々と試してみたのですが、やはりできなかったので、質問させていただくことにしました。
結果としては、print関数で昇順に表示出来ればいいのですが・・・。
以下のコードのどこをどう変えれば良いのか、ご指摘の方、何卒よろしくお願い致します。
#include <iostream>
#include <vector>
using namespace std;

class Array {
private:
vector<int> array;
public:
void insert( int value ){ array.push_back( value ); }
int getSize( ){ return (int)array.size( ); }
void quick_sort( ){ quick_sort( 0, (int)array.size( ) - 1 ); }
void quick_sort( int left, int right );
int partition( int left, int right );
void swap(int *a,int *b){int tmp=*a;*a=*b;*b=tmp;}
void print( );
};

// クイックソートにより配列の添字 left ~ right の部分を整列する関数
void Array::quick_sort( int left, int right ) {

if ( left >= right ) {
return;
}

int v = partition( left, right );

quick_sort( left, v - 1 );
quick_sort( v + 1, right );
}

//この関数を考える
// 配列の添字 left ~ right の部分を,pivot の値より小さい要素と,大きい要素に分割し pivot の位置を返す関数
int Array::partition( int left, int right ) {

int i=left; //左からの処理位置
int j=right; //右からの処理位置
int pivot=array[(int)(left+right)/2]; //基準
int tmp=0;

while(true){
while(array[i]<pivot){i++;}
while(array[j]>pivot){j--;}
if(i>=j){return i;}
tmp=array[i];
array[i]=array[j];
array[j]=tmp;
i++;
j++;
}
}

// 配列の内容を表示する関数
void Array::print( ) {
for ( int i = 0; i < (int)array.size( ); i++ ) {
cout << array[i] << " ";
}
cout << endl;
}

int main( ) {

Array a1;

a1.insert( 56 );
a1.insert( 34 );
a1.insert( 57 );
a1.insert( 64 );
a1.insert( 3 );
a1.insert( 87 );
a1.insert( 85 );
a1.insert( 37 );
a1.insert( 21 );
a1.insert( 4 );
a1.insert( 68 );
a1.insert( 62 );
a1.insert( 42 );
a1.insert( 55 );
a1.insert( 63 );
a1.insert( 95 );
a1.insert( 7 );
a1.insert( 32 );
a1.insert( 78 );
a1.insert( 11 );

cout << "要素数: " << a1.getSize( ) << endl;
cout << "ソート前: ";
a1.print( );

a1.quick_sort( ); // ここで,ソートを行う関数を呼び出す

cout << "ソート後: ";
a1.print( );

return 0;
}

投稿日時 - 2016-01-20 20:43:00

QNo.9114453

すぐに回答ほしいです

質問者が選んだベストアンサー

添え字の範囲の検査が必要です.作り変えてみました.
// 配列の添字 left ~ right の部分を,pivot の値より小さい要素と,大きい要素に分割し pivot の位置を返す関数
int Array::partition(int left, int right) {
int ipivot = left + (right - left) / 2;
int pivot = array[ipivot]; //基準
Array::swap(&array[left], &array[ipivot]); //基準値を先頭に退避する

int j = right; //右からの処理位置
int i = left + 1; //左からの処理位置

while (true){
while (array[j]>pivot){ j--; }
while (i <= j && array[i] < pivot){ i++; }
if (i >= j) break;
this->swap(&array[i], &array[j]);
i++;
j--;
}
this->swap(&array[left], &array[j]); //基準値をPartition位置に戻す
return j;
}

投稿日時 - 2016-01-21 01:21:56

お礼

見づらいコードだったにも関わらず、丁寧に解読、ご返答してくださり、本当に有難うございました。
解答してくださった関数を、自分なりに解読して理解しようと思います。

投稿日時 - 2016-01-21 12:44:54

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(1)

-広告-
-広告-

あなたにオススメの質問

-広告-
-広告-