关于选择排列的语法提问
自己编写的选择排列语法,一直在修改都未获成功。。已经想了一个晚上了,还是不知道错在哪里{:10_266:} 望高手指点迷津!#include <stdio.h>
#define N 10
int main(void)
{
int i, j, k,l, temp, num,max_id;
printf("Enter 10 numbers: ");
for (i = 0; i < N; i++)
{
scanf_s("%d", &num);
}
for (j = N - 1; j >= 0; j--)
{
max_id = j;
for (k =1; k <N - j ; k++)
{
if (num > num)
{
max_id = k;
}
}
if (max_id != j)
{
temp = num;
num = num;
num = temp;
}
}
for (l = 0; l < N; i++)
{
printf("%d", num);
}
return 0;
} 选择排序是冒泡排序的一种变形,每次循环都找出一个最大值或最小值,我先简单给出你这个的标准形式,再看看你代码的问题在哪里 for (j = N - 1; j >= 0; j--)
{
max_id = j;
for (k = j-1; k >=0; k--)
{
if (num < num)
{
max_id = k;
}
}
if (max_id != j)
{
temp = num;
num = num;
num = temp;
}
}
排序算法部分的改动 倒戈卸甲 发表于 2020-4-22 22:01
选择排序是冒泡排序的一种变形,每次循环都找出一个最大值或最小值,我先简单给出你这个的标准形式,再看看 ...
非常感谢你的帮助!{:7_146:}修改了第二个for语句的循环条件就能成功运行了!看来我在对嵌套循环的知识了解得还不够透彻,我得继续钻研钻研。 倒戈卸甲 发表于 2020-4-22 21:31
选择排序是冒泡排序的一种变形,每次循环都找出一个最大值或最小值,我先简单给出你这个的标准形式,再看看 ...
答主不好意思打扰了!我还有一个地方比较迷惑:按理说我是将最大值赋予了最后一位数字,正常情况下不应该是按照从小到大排序吗?可结果怎么就成了从大到小{:10_291:} if (num < num)
{
max_id = k;
}
}
中使用大于号或小于号能分别控制正序逆序 sulley 发表于 2020-4-22 22:26
答主不好意思打扰了!我还有一个地方比较迷惑:按理说我是将最大值赋予了最后一位数字,正常情况下不应该 ...
不过你原先思路应该和我的代码不同,里面的问题我一时半会儿还没找到 本帖最后由 sulley 于 2020-4-22 22:57 编辑
倒戈卸甲 发表于 2020-4-22 22:42
不过你原先思路应该和我的代码不同,里面的问题我一时半会儿还没找到
我试过之后成功了!答主好厉害!!谢谢你!C语言的循环真的好神奇啊!今天实在是麻烦你了!非常感谢!今天长知识了 本帖最后由 倒戈卸甲 于 2020-4-23 11:34 编辑
sulley 发表于 2020-4-22 22:26
答主不好意思打扰了!我还有一个地方比较迷惑:按理说我是将最大值赋予了最后一位数字,正常情况下不应该 ...
for (int i = 0; i <len; i++)
{
int M = i;
for (int j = i+1; j < len; j++)
{
if (arr > arr) {
M = j;
}
if (i!=M)
{
temp=arr;
arr=arr;
arr=temp;
}
}
上面是最基础的选择排序法,通过if (arr > arr)或者if (arr < arr)分别实现升序和降序。这个代码的排序逻辑几乎等同于冒泡排序,第一轮排序比较len-1次,在全部len个值中找到最小值,并将其序号设为0,第二轮排序比较len-2次,在剩下len-1个值中找到最小值,并将其序号设为1......通过len-1轮排序就实现了数组排序。
而你的算法很有意思,虽然有错误,但整体思路是:第一轮只比较0次,选择的数序号不变,仍为n-1,第二轮比较1次,把小的那个序号设为n-2... ...最后一轮才比较n-1次,我要好好琢磨一下 倒戈卸甲 发表于 2020-4-22 22:59
for (int i = 0; iarr) {
M = j;
}
嗯,想明白了,你的思路通过选择排序算法不能实现。因为选择排序每轮只“挑出”最大数或最小数,虽然有多次比较,但比较完只交换下标,最后才进行至多一次实质上的数字交换。但你的这个思路必须要第n轮排序可以交换n次数字才行 倒戈卸甲 发表于 2020-4-22 23:07
嗯,想明白了,你的思路通过选择排序算法不能实现。因为选择排序每轮只“挑出”最大数或最小数,虽然有多 ...
那么请问下这个修改后能够正确运行的代码本质上是起泡排序吗
#include <stdio.h>
#define N 10
int main(void)
{
int i, j, k, temp, max_id, num;
printf("Enter 10 numbers: ");
for (i = 0; i < N; i++)
{
scanf_s("%d", &num);
}
for (j = N - 1; j >= 0; j--)
{
max_id = j;
for (k = j - 1; k >= 0; k--)
{
if (num > num)
{
max_id = k;
}
}
if (max_id != j)
{
temp = num;
num = num;
num = temp;
}
}
for (i = 0; i < N; i++)
{
printf("%d ", num);
}
} 本帖最后由 sulley 于 2020-4-22 23:29 编辑
倒戈卸甲 发表于 2020-4-22 23:07
嗯,想明白了,你的思路通过选择排序算法不能实现。因为选择排序每轮只“挑出”最大数或最小数,虽然有多 ...
我突然间又变懵了{:10_266:}一开始我写的线面的语法老师说是起泡排序,要修改为选择排序。今天下午到现在都在努力分清他们的区别。就目前我的认知层次是,起泡排序是分组两两比较数字,不符合条件的的交换,而选择排序是交换下标。两者似乎都要交换过很多次,实则不然。
我不明白怎么直接将最值与目标下标交换了{:10_266:}实在抱歉,又打扰你了
#include <stdio.h>
#define N 10//假设是将10个数字进行排列
int main (void)
{
int a;
int i, j, k;
printf("请%d个待排序数字: ",N);
for (i = 0; i < N; i++)
scanf_s("%d", &a);
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
if (a < a)
{
k = a;
a = a;
a = k;
}
}
printf("排序后数字为:\n");
for (i = 0; i < N; i++)
printf("%4d", a);
printf("\n");
return 0;
}
本帖最后由 倒戈卸甲 于 2020-4-22 23:35 编辑
倒戈卸甲 发表于 2020-4-22 22:59
for (int i = 0; iarr) {
M = j;
}
void sort(int arr[],int len)
{
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (arr > arr)
{
int temp = arr;
arr = arr;
arr = temp;
}
}
}
}
这个是冒泡排序,学校都会教这个,跟选择排序相比,冒泡选择每次比较都会更正被比较的两个数的大小关系,拿到较大的那个数参与下一次比较。比较多少次就可能最多交换多少次,一轮比较完得出一个最值。而选择排序法,真正拿到的是每次比较后较大的那个数的下标,然后进行下一次比较。一轮比较完拿到最大的那个数的下标,然后才真正进行一次可能的交换。 本帖最后由 倒戈卸甲 于 2020-4-23 11:33 编辑
sulley 发表于 2020-4-22 23:19
那么请问下这个修改后能够正确运行的代码本质上是起泡排序吗
#include
#define N 10
没有,我不是这个意思。选择排序与冒泡排序绝对是两种不同的算法,我说的几乎等同是指它每轮比较达成的结果,以及每轮进行的比较次数 倒戈卸甲 发表于 2020-4-22 23:34
没有,我不是这个意思。选择排序与冒泡排序绝对是两种不同的算法,我说的几乎等同是指它每轮比较达成的目 ...
哦哦!恕我愚钝!我终于理解了!!!非常感谢您今天的耐心讲解呀~ 本帖最后由 倒戈卸甲 于 2020-4-23 00:10 编辑
sulley 发表于 2020-4-22 23:26
我突然间又变懵了一开始我写的线面的语法老师说是起泡排序,要修改为选择排序。今天下午到现 ...
其实理解起来还是很简单的。举个例子就行。假设数组中最大的数为a,长度为x,只讨论第一轮排序。
冒泡排序进行x-1次比较,第5次比较会将a与a交换,使a变为最大值;第6次比较会将a与a交换,使a变为最大值。。。。第n-1次比较会将将a与a交换,使a变为最大值.
=========
选择排序也进行x-1次比较,但它是用一个变量M来记录下标,最先是令下标为0 ,然后a与a比较,假设a大就令M=1,否则M还是为0。第四次比较的时候,a与a比较,此时M的取值可能为0/1/2/3中的任何一个,谁是前面的最大值,M就等于它的下标。不过没关系,因为a最大,这次比较完后,M的值会一直为4。然后就是 if (i!=M)
{
temp=arr;
arr=arr;
arr=temp;
}
这段代码,因为最终M的值为4,并非循环开始时首元素的下标,说明首元素不是最大值。而此时M记录了最大值下标,把a交给首元素就好。
倒戈卸甲 发表于 2020-4-22 23:56
其实理解起来还是很简单的。举个例子就行。假设数组中最大的数为a,长度为x,只讨论第一轮排序。
...
这里举例没仔细去考虑,冒泡排序的结果是升序,选择排序的结果是降序。不过这不影响,选择排序要降序的话,每次比较拿到较小值下标就行,也不要盯着a不放了,去盯着数组中最小的那个数就行 倒戈卸甲 发表于 2020-4-22 23:56
其实理解起来还是很简单的。举个例子就行。假设数组中最大的数为a,长度为x,只讨论第一轮排序。
...
感激涕零!{:10_254:{:10_254:}{:10_254:} sulley 发表于 2020-4-23 00:04
感激涕零!{:10_254:
{:10_256:}其实这样我也顺便复习一下排序算法,对我自己挺有好处的 倒戈卸甲 发表于 2020-4-23 00:07
其实这样我也顺便复习一下排序算法,对我自己挺有好处的
向大佬学习!{:10_329:} sulley 发表于 2020-4-23 00:20
向大佬学习!
其实这个论坛的大佬都在python板块{:10_256:}
如果你是用python写的排序算法早就一大群大佬围上来了。
而我学python的时间还不够长,平时用的又少,还有很长的路要走{:10_254:}
页:
[1]
2