ç随机支点的快速排序(改善分区功能) [英] C randomized pivot quicksort (improving the partition function)

查看:194
本文介绍了ç随机支点的快速排序(改善分区功能)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一名计算机专业的学生(刚开始),我正在从伪$ C $编写C语言快速排序的随机支点版本。我已经编写和测试它,它的所有作品完美但...

分区部分看起来有点太复杂了,因为感觉我错过了一些东西,或overthought它。如果它是确定或我不明白,如果我做了一些可以避免的错误。

所以长话短说:它的工作原理,但如何做的更好。

在此先感谢所有帮助

 无效分区(int类型的[],诠释开始,诠释完)
{
    函数srand(时间(NULL));
    INT pivotpos = 3; //启动+兰特()%(年底启动);
    INT I =启动; //指数1
    INT J =结束; //指数2
    INT标志= 1;
    INT支点= A [pivotpos]; //设置支点的价值
    而(I< J&安培;&安培;标志)//主循环
    {
        标志= 0;
        而(一个[1] - ;枢轴)
        {
            我++;
        }
        而(A [J]>透视)
        {
            j--;
        }
        如果(A [I]>将研究[J])//交换和放大器;&安培;确立了新的支点,并恢复标志
        {
            掉期(安培; A [I],和放大器;一个[J]);
            如果(pivotpos == I)
                pivotpos = j的;
            否则,如果(pivotpos == j)条
                pivotpos = I;
            标志++;
        }
        否则,如果(A [I] ==一个[J])//避免了价值观的镜像越来越闹心(FX支点上的POS 3:1-0-0-1-1)
        {
            如果(pivotpos == I)
                j--;
            否则,如果(pivotpos == j)条
                我++;
            其他
            {
                我++;
                j--;
            }
            标志++;
        }
    }
}


解决方案

这是的伪code分区()来自的算法导论,这就是所谓Lomuto的划分算法,并且有在书中它下面一个很好的解释。

  PARTITION(A,P,R)
1×←A [R]
2我←对 - 1
3对于j←p来的R - 1
4做,如果A [J]≤点¯x
5我←I + 1
6交流[I]↔A [J]。
7交流[I + 1]↔A [R]
8回报,我+1

您可以轻松实现基于上面的伪code随机分区实施。正如评论指出的那样,移动函数srand()分区

  //函数srand(时间(NULL));
INT分区(INT *改编,诠释开始,诠释完)
{
    INT pivot_index =启动+兰特()%(结束 - 开始+ 1);
    INT支点= ARR [pivot_index]    掉期(安培;常用3 [pivot_index],和放大器;常用3 [结束]); //交换随机支点结束。
    pivot_index =结束;
    INT I = -1开始;    对于(INT J =启动; J< =结束 - 1; J ++)
    {
        如果(ARR [J]< =支点)
        {
            我++;
            掉期(安培;常用3 [I],和放大器;常用3 [J]);
        }
    }
    掉期(安培;常用3 [I + 1],&安培; ARR [pivot_index]); //放置支点正确的地方    返回I + 1;
}

和没有在书中提到的另一种划分方法,被称为霍尔的划分算法,伪code是如下:

 霍尔 - 分区(A,P,R)
X = A [P]
我= P - 1
J = R + 1
而真正的
    重复
        当J = J - 1
    直到[J]< = X
    重复
        I = I + 1
    直到[I]> = X
    如果我< Ĵ
        掉期(A [I],A [J]。)
    其他
        复位J

分区后,在一个[P ... J]每一个元素≤一中的每一个元素[J + 1 ... R]。因此,快速排序是:

  QUICKSORT(A,P,R)
如果P< ,则成为
 Q =霍尔 - 分区(A,P,R)
 QUICKSORT(A,P,Q)
 QUICKSORT(A,Q + 1,R)

I'm a computer science student (just started), I was working on writing from pseudocode a randomized pivot version of Quicksort. I've written and tested it, and it all works perfectly however...

The partition part looks a bit too complicated, as it feels I have missed something or overthought it. I can't understand if it's ok or if I made some avoidable mistakes.

So long story short: it works, but how to do better?

Thanks in advance for all the help

void partition(int a[],int start,int end)
{
    srand (time(NULL));
    int pivotpos = 3;   //start + rand() % (end-start);
    int i = start;    // index 1
    int j = end;      // index 2
    int flag = 1;
    int pivot = a[pivotpos];   // sets the pivot's value
    while(i<j && flag)      // main loop
    {
        flag = 0;
        while (a[i]<pivot)
        {
            i++;
        }
        while (a[j]>pivot)
        {
            j--;
        }
        if(a[i]>a[j]) // swap && sets new pivot, and restores the flag
        {
            swap(&a[i],&a[j]);
            if(pivotpos == i)
                pivotpos = j;
            else if(pivotpos == j)
                pivotpos = i;
            flag++;
        }
        else if(a[i] == a[j])       // avoids getting suck on a mirror of values (fx pivot on pos 3 of : 1-0-0-1-1)
        {
            if(pivotpos == i) 
                j--;
            else if(pivotpos == j)
                i++;
            else
            {
                i++;
                j--;
            }
            flag++;
        }
    }
}

解决方案

This is the pseudo code of partition() from Introduction to Algorithms , which is called Lomuto's Partitioning Algorithm, and there's a good explanation below it in the book.

PARTITION(A, p, r)
1 x ← A[r]
2 i ← p - 1
3 for j ← p to r - 1
4   do if A[j] ≤ x
5       then i ←i + 1
6           exchange A[i] ↔ A[j]
7 exchange A[i + 1] ↔ A[r]
8 return i +1

You can implement a randomized partition implementation easily based on the pseudo code above. As the comment pointed out, move the srand() out of the partition.

// srand(time(NULL));
int partition(int* arr, int start, int end)
{
    int pivot_index = start + rand() % (end - start + 1);
    int pivot = arr[pivot_index ];

    swap(&arr[pivot_index ], &arr[end]); // swap random pivot to end.
    pivot_index = end;
    int i = start -1;

    for(int j = start; j <= end - 1; j++)
    {
        if(arr[j] <= pivot)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[pivot_index]); // place the pivot to right place

    return i + 1;
}

And there is another partition method mentioned in the book, which is called Hoare's Partitioning Algorithm, the pseudo code is as below:

Hoare-Partition(A, p, r)
x = A[p]
i = p - 1
j = r + 1
while true
    repeat
        j = j - 1
    until A[j] <= x
    repeat
        i = i + 1
    until A[i] >= x
    if i < j
        swap( A[i], A[j] )
    else
        return j

After the partition, every element in A[p...j] ≤ every element in A[j+1...r]. So the quicksort would be:

QUICKSORT (A, p, r)
if p < r then
 q = Hoare-Partition(A, p, r)
 QUICKSORT(A, p, q)
 QUICKSORT(A, q+1, r)

这篇关于ç随机支点的快速排序(改善分区功能)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆