题目:
有一个顺序表L,假设元素类型ElemType为整型,以第一个元素为分界线(基准),将所有小于等于它的元素移到该基准的前面,将大于它的移到该基准的后面。
思路:
可以从顺序表的两端开始扫描,左边扫描到小于等于基准则跳过不移动,大于基准的则与当前右边下标为j的交换,右边扫描到大于基准则跳过不移动,小于等于基准的则与当前左边下标为i的交换。
以下用了两种方法来做这题,这两种方法的时间复杂度都是O(n),空间复杂度是O(1),但使用方法二会更好,因为第2个算法中移动元素的次数更少
代码:
法1:
void Move(seqlist*& L) {
//第一个元素
int r = L->data[0];
//将后面的元素从两端扫描进行排序
int i = 1, j = L->length - 1;
while (i<j)
{
while (i<j&&L->data[j]>r)
{
//右边元素大于r则跳过,查找下一个
j--;
}
while (i<j&&L->data[i]<=r)
{
//左边元素小于等于r则跳过,查找下一个
i++;
}
//不符合上面两种情况则交换
if (i < j) {
swap(L->data[i], L->data[j]);
}
}
//最后交换r和第i处的数值
swap(L->data[0], L->data[i]);
}
法2:
void Move(seqlist*& L) {
//第一个元素
int r = L->data[0];
//将后面的元素从两端扫描进行排序
int i = 1, j = L->length - 1;
while (i<j)
{
while (i<j && L->data[j]>r) {
j--;
}
L->data[i] = L->data[j];
while (i < j && L->data[i] <= r) {
i++;
}
L->data[j] = L->data[i];
}
L->data[i] = r;
}