[英]How to implement Quicksort in C with pointers?
因此,我目前正在將Java quicksort程序轉換為C,但是不確定是否正確使用了指針。 據我所知,我相信我在分區方法中正確使用了它們,或者至少我的語法是正確的-我沒有收到任何錯誤。 我是; 但是,得到與我的結果相同的數組。 我當前的程序是
'
// quickSort.c
#include <stdio.h>
#include <stdlib.h>
#
void swap(int *a, int *b);
void quickSort( int[], int, int);
int partition( int*, int, int);
int main(int argc, char *argv[])
{
int a[] = {2, 6, 5, 1};
int i;
// int arrlength = sizeof(a); WRONG
int arrlength = 4;
printf("\n\nUnsorted array is: ");
for(i = 0; i < arrlength; ++i)
printf(" %d ", a[i]);
//array, 0, length
quickSort( a, 0, arrlength);
printf("\n\nSorted array is: ");
for(i = 0; i < arrlength; ++i)
printf(" %d ", a[i]);
printf("\n\n");
}
// char yo[] = "Hello";
// &yo[0] = will be equivalent to = Hello &yo[0] points to variable yo[0]
//array, Leftmost position, Rightmost position
void quickSort( int a[], int L, int R)
{
int k;
if( R <= L){
return;
}
k = partition( a, L, R);
quickSort( a, L, k); // Sort left half of partitioned array
quickSort( a, k+1, R); // Sort right half of partitioned array
}
// L= leftmost position in the array
// R= rightmost position in the array
// int *a = pointer to array we are sorting
int partition(int a[], int L, int R) {
// [2 , 6 , 5 , 1]
// | |
// | | once the two pointers cross we exist the while loop.
// | |
// S B=4 & p[B]=1
int pivot;
int help;
int S;
int B;
S = L; //S = current Leftmost position
B = R-1;//B = rightmost position
pivot = a[R-1]; //rightmost number in array
int *pop;
pop = &a[B]; //pop points to address of array
//*pop is the actual variable in the address a[B]
while(B > S) {//as long as the two pointers don't cross you continue
if(a[B-1] > pivot){ //move to the right of the pivot
pop = &a[B-1];
B--;
}
else {
swap(&a[B-1], &a[S]);// move to left of the pivot
S++;
}
}
pop = &pivot; // Put pivot in the "hole"
return B; //return the position of the pivot
}
void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
// Unsorted array is: 2 6 5 1
// Sorted array is: 2 6 5 1
// First partition:
// pivot = 1;
// 2,6,5,5
// 2,6,6,5
// 2,2,6,5
// escape while loop
// 1,2,6,5
'
如果有人想看我的Java程序,就是這樣:'import java.util.Arrays;
public class AltSorts {
public static void QuickSort( double[] a, int L, int R ){
int k;
if ( R <= L){
return;
}
k = partition( a, L, R );
QuickSort( a, L, k ); // Sort left half of partitioned array
QuickSort( a, k+1, R); // Sort right half of partitioned array
}
public static int partition( double[] a, int L, int R )
{
double pivot;
double help;
int S;
int B;
/**
[2 , 6 , 5 , 1]
| |
| | once the two pointers cross we exist the while loop.
| |
S B=4 & p[B]=1
* */
S = L; //S = current Leftmost position
B = R-1;//B = rightmost position
pivot = a[R-1]; //rightmost number in array
while ( B > S )//as long as the two pointers don't cross you continue
{
if ( a[B -1] > pivot ){ //move to the right of the pivot
a[B] = a[B -1];
B--;
}
else
{
help = a[B -1]; // move to left of the pivot
a[B -1] = a[S];
a[S] = help;
S++;
}
}
a[B] = pivot; // Put pivot in the "hole"
return B; //return the position of the pivot
}
public static void main( String[] args )
{
double[] x = {2, 6, 5, 1};
System.out.println("Before sort: " + Arrays.toString(x) + "\n" );
QuickSort( x, 0, x.length ); // Quick sort
System.out.println("\nAfter sort: " + Arrays.toString(x) );
}
}
'
HuStmpHrrr指出了源代碼中的一些問題。 而且,多虧了他,我才能夠弄清你做錯了什么。
分區例程的結果是不平衡的(看看“ pop”以及分區函數的返回值)
我在實現后編寫了此代碼(進行了一些更改)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
/// Function prototypes
void
swap( int *a, int *b );
void
quickSort( int *a, int low, int high );
int
partition( int *a, int low, int high );
int main( int argc, const char * argv[] ) {
// insert code here...
int a[] = { 2, 6, 5, 1 };
quickSort( a, 0, 3 );
for ( int i = 0; i < 4; ++i ) {
printf( "%d ", a[ i ] );
}
return EXIT_SUCCESS;
}
/// Function definitions
void
swap( int *a, int *b )
{
assert( a != NULL );
assert( b != NULL );
int temp = *a;
*a = *b;
*b = temp;
}
void
quickSort( int *a, int low, int high )
{
assert( a != NULL );
if ( high <= low ) {
return;
}
int k = partition( a, low, high );
quickSort( a, low, k - 1 ); /// Sort left part
quickSort( a, k + 1, high ); /// Sort right part
}
int
partition( int *a, int low, int high )
{
assert( a != NULL );
bool flag = false;
int first = low; /// Left indice
int last = high +1; /// Right indice
int pivot = a[ low ]; /// Partitioning item
while ( !flag ) {
while ( a[ ++first ] < pivot ) { /// Scan left and move
if ( first == high) flag = true;
}
while ( a[ --last ] > pivot ) { /// Scan right and move
if ( last == low ) flag = true;
}
if ( first >= last ) {
flag = true;
}
else {
swap( &a[ first], &a[ last ] );
}
}
swap( &a[ low ], &a[ last ] );
return last;
}
// quickSort.c
#include <stdio.h>
#include <stdlib.h>
#
void swap(int *a, int *b);
void quickSort( int *a, int, int);
int partition( int *a, int, int);
int main(int argc, char *argv[])
{
int a[] = {0, 2, 6, 5, 1};
int i;
// int arrlength = sizeof(a); WRONG
int arrlength = 5;
printf("\n\nUnsorted array is: ");
for(i = 0; i < arrlength; ++i)
printf(" %d ", a[i]);
//array, 0, length
quickSort( a, 0, arrlength);
printf("\n\nSorted array is: ");
for(i = 0; i < arrlength; ++i)
printf(" %d ", a[i]);
printf("\n\n");
}
// char yo[] = "Hello";
// &yo[0] = will be equivalent to = Hello &yo[0] points to variable yo[0]
//array, Leftmost position, Rightmost position
void quickSort( int *a, int L, int R)
{
int k;
if( R <= L){
return;
}
k = partition( a, L, R);
quickSort( a, L, k); // Sort left half of partitioned array
quickSort( a, k+1, R); // Sort right half of partitioned array
}
// L= leftmost position in the array
// R= rightmost position in the array
// int *a = pointer to array we are sorting
int partition(int *a, int L, int R) {
// [2 , 6 , 5 , 1]
// | |
// | | once the two pointers cross we exist the while loop.
// | |
// S B=4 & p[B]=1
int pivot;
int help;
int Small;
int Big;
Small = L; //S = current Leftmost position
Big = R-1;//B = rightmost position
pivot = a[R-1]; //rightmost number in array
while(Big > Small) {//as long as the two pointers don't cross you continue
if(a[Big-1] > pivot){ //move to the right of the pivot
swap(&a[Big], &a[Big-1]); //HERE IS THE CHANGE I MADE!!!!!!!!!!!
Big--;
}
else {
swap(&a[Big-1], &a[Small]);// move to left of the pivot
Small++;
}
}
//HERE IS THE CHANGE I MADE!!!!!!!!!!!
//pop
//pop = &pivot; // Put pivot in the "hole"
return Big; //return the position of the pivot
}
void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
盡管您的答案是正確的,但它的確使我大失所望。 我要做的就是刪除pop =&pivot,並且在項大於樞軸時才對數組使用swap方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.