题目描述:有个存放整数类型的顺序表L,设计算法将L中所有⼩于等于表头元素的整数放在前半部分,⼤于表头元素的整数放在后半部分。
感谢多动症男孩队长提供的·知识帮助,自己做的时候可以画一下图理解下:
知识点&注意点:
1. 交换元素时,右指针指向的元素要⼩于等于表头元素,左指针指向的元素要⼤于表头元
素。这样可以保证交换后的顺序表仍然满⾜题⽬要求:将⼩于等于表头元素的整数放在前
半部分,⼤于表头元素的整数放在后半部分。
2. 外层循环中left<=right的条件,其中=是为了保证循环结束的时候right指向左边最后⼀个
⼩于表头值的元素,⽅便最后的时候⼀个把表头元素放到合适的位置(即左边都是⼩于它
的元素,右边都是⼤于它的元素)
时间复杂度:O(n),其中n为顺序表中元素的个数。因为我们需要遍历整个顺序表,并且只进
⾏值的交换操作。
空间复杂度:O(1),即常数级别。算法并没有使⽤额外的数据结构来存储元素。
思路:
1. 定义两个指针,⼀个指针从表头开始向后遍历,找到⼤于表头元素的整数;另⼀个指针从表尾开始向前遍历,找到⼩于等于表头元素的整数。
2. 在遍历的过程中,如果左指针指向的元素⼤于表头元素,右指针指向的元素时⼩于等于表头元素的指针,则交换两个指针指向的元素(这⾥只需要交换值即可)。
3. 重复步骤2,直到两个指针相遇(此时表⽰整个顺序表已经遍历完毕)。
参考伪代码:
void partition(int* data,int length){
if(data == NULL || length==0){
return -1; //返回错误
}
int target = data[0]; //存储表头元素便于作比较
int left=1; //定义左指针指向第二个元素
int right=length-1; //定义右指针指向最后一个元素
while(legt<=right){
while(data[left]<=target){
left++;
}
while(data[right]>target){
right--;
}
if(left<right){ //当左右指针不满足各自条件时,就交换它们对应的元素
int temp1 = data[left]
data[left] = data[right]
data[right] = temp;
left++;
right--;
}
}
//此时右指针指向时左边最后一个小于表头元素的元素,将它与表头元素互换位置
int temp2 = data[0];
data[0] = data[right];
data[right] = temp2;
}