首页 > 代码库 > 算法(二):快速排序

算法(二):快速排序

(1)选择中值,根据坐标,三者取其中

(2)分别与中值比较,将数据分成两部分

(3)两部分中分别再使用同样的方法,分成更小的两部分,直到不可再分

(4)qksort中的递归,可以保证a[0]~a[j]完全排序,所以i = j+1;


代码:

root@ubuntu:/mnt/shared/appbox/qksort# cat qksort.c
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

static int compare_int(const void *int1, const void *int2)
{
        if(*(const int *)int1 == *(const int *)int2)
                return 0;

        return *(const int *)int1 > *(const int *)int2 ? 1 : -1;
}
static int get_mid_value(int *data)
{
        if(compare_int(&data[0], &data[1])>0)//d[0]>d[1]
        {
                if(compare_int(&data[0], &data[2]) > 0)
                        return compare_int(&data[1], &data[2]) > 0 ? data[1] : data[2];
                else
                        return data[0];
        }
        else // d[0] < d[1]
        {
                if(compare_int(&data[0], &data[2]) > 0)//d[0] > d[2]
                        return data[0]; // d[2]<d[0]<d[1], return d[0]
                else//d[0] < d[2]
                        return compare_int(&data[1] ,&data[2]) > 0? data[2]:data[1];
        }

        return -1;
}

static int partition(int *a, int esize, int i, int k, int (*compare)(const void *key1, const void *key2))
{
        int m;
        int mid, middle;
        int r[3];
        int temp;

        r[0] = (rand()%(k-i+1) + i);
        r[1] = (rand()%(k-i+1) + i);
        r[2] = (rand()%(k-i+1) + i);

        mid = get_mid_value(r);
        middle = a[mid];
        printf("r[0]:%d, r[1]:%d, r[2]:%d, mid:%d,middle:%d\n", r[0],r[1],r[2],mid, middle);

        i--;
        k++;

        while(1)
        {
                do
                {
                        k--;
                }while(compare(&a[k], &middle) > 0);

                do
                {
                        i++;
                }while(compare(&a[i], &middle) < 0);

                if(i>=k)
                        break;
                else
                {
                        temp = a[i];
                        a[i] = a[k];
                        a[k] = temp;
                }
        }

        return k;
}

int qksort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2))
{
        int j;
        int m;

        while(i < k)
        {
                if((j = partition(data, esize, i, k, compare)) < 0)
                        return -1;


                if(qksort(data, size, esize, i, j, compare) < 0)
                        return -1;

                i = j + 1;
        }
        return 0;
}

int main(int argc, char *argv[])
{
        int ret;
        int i, j, k;
        i = 11;
        j = 12;
        int array[10]= {1,4,7,2,5,8,3,6,9,10};

        printf("\n******************compare_init test**********************\n");
        printf("compare_int(&i, &j)=%d\n", compare_int(&i, &j));
        printf("compare_int(&j, &i)=%d\n", compare_int(&j, &i));
        printf("compare_int(&i, &i)=%d\n", compare_int(&i, &i));
        printf("\n******************partition    test**********************\n");

        qksort(array, 10, 4, 0, 9, compare_int);

        for(i=0; i<10; i++)
                printf("%d ", array[i]);
        printf("\n");

        return 0;
}

执行结果:



root@ubuntu:/mnt/shared/appbox/qksort# ./qksort 


******************compare_init test**********************
compare_int(&i, &j)=-1
compare_int(&j, &i)=1
compare_int(&i, &i)=0


******************partition    test**********************
r[0]:3, r[1]:6, r[2]:7, mid:6,middle:3
r[0]:1, r[1]:2, r[2]:1, mid:1,middle:3
r[0]:0, r[1]:0, r[2]:1, mid:0,middle:1
r[0]:6, r[1]:5, r[2]:8, mid:6,middle:4
r[0]:6, r[1]:5, r[2]:9, mid:6,middle:7
r[0]:5, r[1]:4, r[2]:4, mid:4,middle:5
r[0]:5, r[1]:5, r[2]:6, mid:5,middle:6
r[0]:9, r[1]:7, r[2]:7, mid:7,middle:8
r[0]:8, r[1]:8, r[2]:8, mid:8,middle:9
1 2 3 4 5 6 7 8 9 10 
root@ubuntu:/mnt/shared/appbox/qksort# 

增加对流程的打印:

root@ubuntu:/mnt/shared/appbox/qksort# cat qksort.c
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

static int compare_int(const void *int1, const void *int2)
{
        if(*(const int *)int1 == *(const int *)int2)
                return 0;

        return *(const int *)int1 > *(const int *)int2 ? 1 : -1;
}
static int get_mid_value(int *data)
{
        if(compare_int(&data[0], &data[1])>0)//d[0]>d[1]
        {
                if(compare_int(&data[0], &data[2]) > 0)
                        return compare_int(&data[1], &data[2]) > 0 ? data[1] : data[2];
                else
                        return data[0];
        }
        else // d[0] < d[1]
        {
                if(compare_int(&data[0], &data[2]) > 0)//d[0] > d[2]
                        return data[0]; // d[2]<d[0]<d[1], return d[0]
                else//d[0] < d[2]
                        return compare_int(&data[1] ,&data[2]) > 0? data[2]:data[1];
        }

        return -1;
}

static int partition(int *a, int esize, int i, int k, int (*compare)(const void *key1, const void *key2))
{
        int m;
        int mid, middle;
        int r[3];
        int temp;

        r[0] = (rand()%(k-i+1) + i);
        r[1] = (rand()%(k-i+1) + i);
        r[2] = (rand()%(k-i+1) + i);

        mid = get_mid_value(r);
        middle = a[mid];
        printf("r[0]:%d, r[1]:%d, r[2]:%d, mid:%d,middle:%d\n", r[0],r[1],r[2],mid, middle);

        i--;
        k++;

        while(1)
        {
                do
                {
                        k--;
                }while(compare(&a[k], &middle) > 0);

                do
                {
                        i++;
                }while(compare(&a[i], &middle) < 0);

                if(i>=k)
                        break;
                else
                {
                        temp = a[i];
                        a[i] = a[k];
                        a[k] = temp;
                }
        }

        return k;
}

int qksort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2))
{
        int j;
        int m;

        while(i < k)
        {
                printf("\n--------------------------------------------------\n");
                printf("i=%d, k=%d\n", i, k);

                for(m=0; m<10; m++)
                        printf("%d ", ((int *)data)[m]);
                printf("\n");

                if((j = partition(data, esize, i, k, compare)) < 0)
                        return -1;

                printf("j=%d, a[j]:%d\n", j, ((int *)data)[j]);

                for(m=0; m<10; m++)
                        printf("%d ", ((int *)data)[m]);
                printf("\n");

                if(qksort(data, size, esize, i, j, compare) < 0)
                        return -1;

                for(m=0; m<10; m++)
                        printf("%d ", ((int *)data)[m]);
                printf("\n");

                i = j + 1;
        }
        return 0;
}

int main(int argc, char *argv[])
{
        int ret;
        int i, j, k;
        i = 11;
        j = 12;
        int array[10]= {1,4,7,2,5,8,3,6,9,10};

        printf("\n******************compare_init test**********************\n");
        printf("compare_int(&i, &j)=%d\n", compare_int(&i, &j));
        printf("compare_int(&j, &i)=%d\n", compare_int(&j, &i));
        printf("compare_int(&i, &i)=%d\n", compare_int(&i, &i));
        printf("\n******************partition    test**********************\n");

        qksort(array, 10, 4, 0, 9, compare_int);

        for(i=0; i<10; i++)
                printf("%d ", array[i]);
        printf("\n");

        return 0;
}
root@ubuntu:/mnt/shared/appbox/qksort# 

输出:

root@ubuntu:/mnt/shared/appbox/qksort# ./qksort    

******************compare_init test**********************
compare_int(&i, &j)=-1
compare_int(&j, &i)=1
compare_int(&i, &i)=0

******************partition    test**********************

--------------------------------------------------
i=0, k=9
1 4 7 2 5 8 3 6 9 10 
r[0]:3, r[1]:6, r[2]:7, mid:6,middle:3
j=2, a[j]:2
1 3 2 7 5 8 4 6 9 10 

--------------------------------------------------
i=0, k=2
1 3 2 7 5 8 4 6 9 10 
r[0]:1, r[1]:2, r[2]:1, mid:1,middle:3
j=1, a[j]:2
1 2 3 7 5 8 4 6 9 10 

--------------------------------------------------
i=0, k=1
1 2 3 7 5 8 4 6 9 10 
r[0]:0, r[1]:0, r[2]:1, mid:0,middle:1
j=0, a[j]:1
1 2 3 7 5 8 4 6 9 10 
1 2 3 7 5 8 4 6 9 10 
1 2 3 7 5 8 4 6 9 10 
1 2 3 7 5 8 4 6 9 10 

--------------------------------------------------
i=3, k=9
1 2 3 7 5 8 4 6 9 10 
r[0]:6, r[1]:5, r[2]:8, mid:6,middle:4
j=3, a[j]:4
1 2 3 4 5 8 7 6 9 10 
1 2 3 4 5 8 7 6 9 10 

--------------------------------------------------
i=4, k=9
1 2 3 4 5 8 7 6 9 10 
r[0]:6, r[1]:5, r[2]:9, mid:6,middle:7
j=6, a[j]:7
1 2 3 4 5 6 7 8 9 10 

--------------------------------------------------
i=4, k=6
1 2 3 4 5 6 7 8 9 10 
r[0]:5, r[1]:4, r[2]:4, mid:4,middle:5
j=4, a[j]:5
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 

--------------------------------------------------
i=5, k=6
1 2 3 4 5 6 7 8 9 10 
r[0]:5, r[1]:5, r[2]:6, mid:5,middle:6
j=5, a[j]:6
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 

--------------------------------------------------
i=7, k=9
1 2 3 4 5 6 7 8 9 10 
r[0]:9, r[1]:7, r[2]:7, mid:7,middle:8
j=7, a[j]:8
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 

--------------------------------------------------
i=8, k=9
1 2 3 4 5 6 7 8 9 10 
r[0]:8, r[1]:8, r[2]:8, mid:8,middle:9
j=8, a[j]:9
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 





算法(二):快速排序