所以,我必须对一个整数数组进行排序,以便每个小于一些scanf
'd整数的数字在左边,这个设置变量在中间,而每个更大的数字在右边。我有左右部分覆盖,但我不知道如何制作它所以变量在中间..任何想法?
#include <stdio.h>
int main()
{
int y, i, k, temp;
printf("give integer\n");
scanf("%d", &y);
int x[10] = {5,8,9,4,2,3,2,4,5,6};
i=0;
k=1;
while(i<10)
{
while(x[i]>y&&k<10)
{
temp=x[k];
x[k]=x[i];
x[i]=temp;
k++;
}
i++;
k=i+1;
}
for(i=0; i<10; i++)
{
printf("x[%d]=%d\n", i, x[i]);
}
}
输入/输出示例:
input: x[i]={5,2,1,6,7,3,2,4,5,6} y=5
output: x[i]={2,1,4,3,2,5,5,7,6,6}
答案 0 :(得分:2)
您可以使用两个数组来降低代码复杂性,而不是使用一个数组。
搜索小于 y
的数字,然后将它们存储在数组中。让我们说A[ ]
再次搜索大于 y
的数字,然后将它们存储在另一个数组B[ ]
中
像这样......
现在你已经拥有了所有这些。您可以将它们存储在另一个可以作为已排序数组调用的数组中。或者如果你只想打印它们,那么
A[ ]
y
B[ ]
这就是全部。希望这个想法可以帮助您快速编码和解决这个问题。
答案 1 :(得分:1)
您正在寻找类似于快速排序算法中的“分区”的算法。我们的想法是有两个索引i
和j
,其中i
用于迭代数组,而j
是第一个项目的索引,大于或等于y
。
在第一个循环之后,您的数字小于左侧的y
和右侧的其他数字。但是,您实际上希望将值分组等于y
,并且右侧只有大于y
的数字。所以我建议在[j,n]区间做同样的事情,但现在我也在等于它时移动。
// Function to exchange the values of 2 integer variables.
void swap(int *a, int *b) {
int buf = *a;
*a = *b;
*b = buf;
}
// Do the job, in place.
void partition(int *tab, int n, int y) {
// This first part will move every values strictly lesser than y on the left. But the right part could be "6 7 5 8" with y=5. On the right side, numbers are greater or equal to `y`.
int j = 0; // j is the index of the position of the first item greater or equal to y.
int i;
for (i = 0; i < n; i++) {
if (tab[i] < y) {
// We found a number lesser than y, we swap it with the first item that is greater or equal to `y`.
swap(&tab[i], &tab[j]);
j++; // Now the position of the first value greater or equal to y is the next one.
}
}
// Basically the same idea on the right part of the array.
for (i = j; i < n; i++) {
if (tab[i] <= y) {
swap(&tab[i], &tab[j]);
j++;
}
}
}
int main() {
int y;
printf("give integer\n");
scanf("%d", &y);
int x[10] = {5,8,9,4,2,3,2,4,5,6};
partition(x, 10, y);
int i;
for(i=0; i<10; i++)
{
printf("x[%d]=%d\n", i, x[i]);
}
return 0;
}
此代码包含x = {5,2,1,6,7,3,2,4,5,6};
和y = 5
:
x[0]=2
x[1]=1
x[2]=3
x[3]=2
x[4]=4
x[5]=5
x[6]=5
x[7]=7
x[8]=6
x[9]=6
前5个元素低于5,其他元素大于或等于5.
答案 2 :(得分:1)
这是一种简单,直接的方法,可以通过分区将数组x排序到另一个数组y中。数字排序&lt; =左边的分区,&gt;右边的分区:
[EDIT] 根据OP说明方法说明方法:
如果数组有2个等于p的元素,那么它应该像这样排列:xxxxxppyyyy其中xp和p不能与x或y混合。
除了示例: xxxxxppyyyy 对于数组来说太长了,所以我认为你的意思是 xxxxppxxxx (10个元素) ,而不是11)。
int * partitionArr(int *z, int p);
int main(void)
{
int i, x[10] = {5,8,9,4,2,3,2,4,5,6};
//int i, x[10] = {3,3,3,3,3,8,8,8,8,8};
int *y;
int partition;
printf("enter a number from 0 to 10\n");
scanf("%d", &partition);
y = malloc(sizeof(int) * sizeof(x)/sizeof(x[0])+1); //+1 for inserting partition
y = partitionArr(x, partition);
printf("Partition is: %d\n\n", partition);
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
printf("y[%d] == %d\n", i, y[i]);
}
getchar();
getchar();
return 0;
}
int * partitionArr(int *z, int p)
{
int i=0,j=0;
int x[10];
//load y with x
for(i=0;i<sizeof(x)/sizeof(x[0]);i++) x[i] = z[i];
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]<p)
{
z[j] = x[i];
j++;
}
}
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]==p)
{
z[j] = x[i];
j++;
}
}
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]>p)
{
z[j] = x[i];
j++;
}
}
return z;
}
以下条件的输出: x&lt; P: x == P; X&LT; p(确保P在中间的唯一方法)
答案 3 :(得分:1)
简单的算法,如果你想通过自己的方式解决这个问题:
[min..y][y+1..max]
,并记下拆分的位置。[min..y-1][y..y]
。现在应该对数组进行分区[min..y-1][y..y][y+1..max]
。
最简单的方法是使用partition_helper函数来执行分区并返回拆分的位置。然后主分区函数使用右参数调用此函数两次。
你也可以用另一种方式进行分区,先[min..y-1][y..max]
,然后将最后一部分重新分区为[y..y][y+1..max]
,最终结果应该相同。