题目
设有一元素为整数的线性表L,存放在一-维数组A[0, . n-1]中,设计一个算法,以A[n-1]为参考量,将该数组分为左右两个部分,其中左半部分的元素值均小于等于A[n-1],右半部分的元素值均大于A[n-1], A[n-1]则位于这两部分之间。要求结果仍存放在数组A中。
分析
第一种思路是,用一个指针从0下标开始向后遍历,如果小于等于A[n-1]则指针向前走,如果遇到大于A[n-1]的情况则临时保存当前的值,然后将当前元素之后的所有元素向前移动一个位置,最后空出来的位置填入刚才临时保存的值,继续遍历比较,直到完成。
第二种思路是,利用两个指针i和j,i从0下标开始,j从n-1下标开始,i指针向后移动,j指针向前移动,当i遇到比基准元素temp小的则指针i++继续移动,当j遇到比基准元素大的则指针j--继续移动,当A[i]遇到大于基准元素temp的情况则交换当前A[i]和A[j]元素的值并且j--向前移动一个位置,当A[j]遇到小于基准元素temp的情况则交换当前A[i]和A[j]元素的值并且i++向后移动一个位置,直到完成所求。
代码
第一种思路的核心代码如下:
/* 将大于num[m-1]的元素都移动到num[m-1]的后面,将小于等于num[m-1]的都移动到其前面 */
/* num[]指的是要移动的数组;m指的是数组中的元素个数 */
void moveEle(int num[],int m){
int temp=num[m-1];// 保存num[m-1]即数组中最后一个元素的值作为比较对象
int i=0;// 计数器
int j=0;// 计数器,统计num[i]>num[m-1]数的个数,也作为循环次数的参考
while(i<m-j){// i最多循环m-j次
if(num[i]<=temp){// 如果小于等于num[m-1]则指针指向下一个元素
i++;// 加1
}else if(num[i]>temp){// 如果大于num[m-1]则移动后面元素的位置
int t=num[i];// 临时保存比num[m-1]大的元素的值
int k;// 计数器,记录移动次数
for(k=i;k<m;k++){// 将t后面的数向前移动一个位置
num[k]=num[k+1];
}
num[k-1]=t;// 然后将t的值赋给数组的最后一个元素
j++;// 计数器+1
}
}
}
完整代码如下:
#include<stdio.h>
/* 4.题目:将大于num[m-1]的元素都移动到num[m-1]的后面,将小于等于num[m-1]的都移动到其前面 */
void print(int num[],int m){
printf("\n");
for(int i=0;i<m;i++){
printf("%d\t",num[i]);
}
printf("\n");
}
/* 将大于num[m-1]的元素都移动到num[m-1]的后面,将小于等于num[m-1]的都移动到其前面 */
/* num[]指的是要移动的数组;m指的是数组中的元素个数 */
void moveEle(int num[],int m){
int temp=num[m-1];// 保存num[m-1]即数组中最后一个元素的值作为比较对象
int i=0;// 计数器
int j=0;// 计数器,统计num[i]>num[m-1]数的个数,也作为循环次数的参考
while(i<m-j){// i最多循环m-j次
if(num[i]<=temp){// 如果小于等于num[m-1]则指针指向下一个元素
i++;// 加1
}else if(num[i]>temp){// 如果大于num[m-1]则移动后面元素的位置
int t=num[i];// 临时保存比num[m-1]大的元素的值
int k;// 计数器,记录移动次数
for(k=i;k<m;k++){// 将t后面的数向前移动一个位置
num[k]=num[k+1];
}
num[k-1]=t;// 然后将t的值赋给数组的最后一个元素
j++;// 计数器+1
}
}
}
int main(){
int num[]={1,4,8,9,2,3,5};
int m=7;
print(num,m);// 打印原数组
moveEle(num,m);
print(num,m);// 打印移动后的数组
}
运行效果如下:
第二种思路的核心代码如下:
void moveEle2(int num[],int m){
int i=0;// i指针的初始下标
int j=m-1;// j指针的初始下标
int temp=num[m-1];// 要作为基准的元素
while(i<j){
while(num[i]<=temp){
i++;
}
if(num[i]>temp){
int t=num[i];
num[i]=num[j];
num[j]=t;
j--;
}
while(num[j]>temp){
j--;
}
if(num[j]<=temp){
int t=num[i];
num[i]=num[j];
num[j]=t;
i++;
}
}
}
运行结果和上面的不一样,因为用的方法是不一样的,但是比A[n-1]小的都在前面,比A[n-1]大的都在后面。