快速排序的一种较简单写法(C语言)
文中的快速排序实际上是快速找到首位元素的实际位置并放置,接着通过二分法,进行递归查找放置,完成排序。
先放代码
void quicksort(int *a,int low,int high)
{
int i=low, j=high;
if(i<j)
return;
int temp=a[low];
while(i<j)
{
while(a[j]>=temp&&i<j)
j--;
a[i]=a[j];
while(a[i]<=temp&&i<j)
i++;
a[j]=a[i];
}
a[i]=temp;
quicksprt(a,low,i-1);
quicksort(a,i+1,high);
}
代码分解
首先我们拿到一组数据a[],找到a[]的最低位下标和最高位下标。接着使用哨兵a[i]和哨兵a[j]查找首位元素a[low]的位置并替换。代码如下:
int temp=a[low];
while(i<j)
{
while(a[j]>=temp&&i<j)
j--;
a[i]=a[j];
while(a[i]<=temp&&i<j)
i++;
a[j]=a[i];
}
a[i]=temp;
查找的核心在于比首元素大的会放在右侧,而比首元素小的会放在左侧。这个操作是怎么完成的,我们首先通过这三行代码完成比首元素大的会放在右侧的操作:
while(a[j]>=temp&&i<j)
j--;
a[i]=a[j];
当a[j]>=temp(首位元素)并且i<j的时候,j向左移一位,直到a[j]<temp(首位元素),a[j]的值赋给等候多时的a[i]。现在,比首元素小的已经放在了左侧,而比首元素大的会随着下面相似的过程完成放置,即:
while(a[i]<=temp&&i<j)
i++;
a[j]=a[i];
六行代码循环往复,完成比首元素大的会放在右侧,而比首元素小的会放在左侧的操作。
上文中我们看到当i<j时,查找才会进行(while(i<j))。随着i++和j–的进行,i和j一定会相等,而i=j时,哨兵a[i]=a[j]的值被赋给别的下标位置,而i=j这个位置就是首元素的位置。我们需要在循环结束加上赋值操作:
a[i]=temp;
现在首元素找到自己的位置,并将数组分为两个区域,接下来就可以用递归来进行循环操作,找到每一个元素的位置并放置。
quicksprt(a,low,i-1);
quicksort(a,i+1,high);
最后,关于为什么要从右开始遍历,这是由于a[low]值被变量temp储存,右侧第一个a[j]比temp大的值会被直接赋给a[low],紧接着进行左侧的遍历,寻找到比temp大的值后赋给右侧a[j]。如果先从左侧遍历,那么最右侧元素的值被a[low]覆盖,程序出错。
以上就是快速排序的一种较简单写法。