鱼C论坛

 找回密码
 立即注册
查看: 253|回复: 8

[已解决]选择排序,K是干啥的以及第二个for循环范围

[复制链接]
发表于 2024-8-25 22:13:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
void selectSort2(int array[ ],int n)
{
         int   i,  j,  k,  t;
        for(i = 0;i < n-1;i++)
        {        k = i;
                for(j = i+1;j < n;j++)
                if(array[j]<array[k])
                k = j;
                t = array[k];array[k] =array[i];array[i] = t;                       
       
        }
}

这是教材上写的。
后边这个是我写的。
void selectSort(int z[ ],int n)
{
        int i,j;
        for(j = 0;j<n-1;j++)
        {
                for(i = j+1;i<n;i++)
                {
                        if(z[j]>z[i])
                        {
                                int t;
                                t = z[j];
                                z[j] = z[i];
                                z[i] = t;

                        }
                }
        }
}
搞不通,教材弄个K沙意识,
教材第二个for范围是那几句

谢谢大家啦
最佳答案
2024-8-26 09:33:44
八义士 发表于 2024-08-26 09:28
您好老师,按照我写的方式不是更简洁吗,为啥一定要有 ...


鱼油您好!

选择排序中使用`k` 或者 `index` 是为了记录最小元素的位置,从而优化代码的可读性和逻辑清晰度。虽然可以在没有 `k` 的情况下直接交换元素,但使用 `k` 可以使代码更加简洁和易于理解。

让我们看看不使用 `k` 的版本和使用 `k` 的版本,进行对比:

### 不使用 `k` 的版本:
void selectSort2(int array[], int n) {
    int i, j, t;
    for(i = 0; i < n - 1; i++) {
        for(j = i + 1; j < n; j++) {
            if(array[j] < array[i]) {
                t = array[i];
                array[i] = array[j];
                array[j] = t;
            }
        }
    }
}

### 使用 `k` 的版本:
void selectSort2(int array[], int n) {
    int i, j, k, t;
    for(i = 0; i < n - 1; i++) {
        k = i;
        for(j = i + 1; j < n; j++) {
            if(array[j] < array[k]) {
                k = j;
            }
        }
        if(k != i) {
            t = array[i];
            array[i] = array[k];
            array[k] = t;
        }
    }
}

**优点总结:**

1. **逻辑清晰**:使用 `k` 明确地表示当前找到的最小值的位置,使得逻辑清楚。
2. **减少不必要的交换**:避免在内层循环中每次找到更小值时都交换元素,从而减少不必要的交换操作,提高运行效率。

虽然不使用 `k` 也可以实现选择排序,但使用 `k` 会让代码更加清晰和高效。需要更少的错误检查和边界情况处理,显得更加专业。

希望这个解释能帮助你理解为什么在选择排序中很多程序都使用 `k` 或 `index` 来记录最小元素的位置。如有其他问题,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-8-25 22:23:30 | 显示全部楼层
k 代表 i ~ n-1 里的最小值的下标
你可以看到, 循环里只要发现 a[k] 大于 a[j] 就立刻把 k 赋值为 j
这样循环结束之后交换最小值和 i 的位置就完成了一次排序
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-25 22:25:03 | 显示全部楼层
鱼油您好!

在这个选择排序的代码片段中,内层 `for` 循环的范围有些模糊,让我给您完整解释一下。
void selectSort2(int array[], int n)
{
    int i, j, k, t;
    for(i = 0; i < n-1; i++)
    {
        k = i;
        for(j = i+1; j < n; j++)
        {
            if(array[j] < array[k])
            {
                k = j;
            }
        }
        if(k != i)
        {
            t = array[i];
            array[i] = array[k];
            array[k] = t;
        }
    }
}

这个选择排序函数的作用是对一个数组进行排序。

1. **外层循环 (for i)**:从数组第一个元素开始,每次增加一次迭代。在第 `i` 次迭代中,外层循环确保从第 `i` 个元素到最后一个元素中选出最小的元素,并将其与第 `i` 个元素交换位置。
   
2. **内层循环 (for j)**:从 `i + 1` 开始,到 `n` 结束,用于找到从 `i` 到最后一个元素中的最小值。
   
3. **条件判断和交换 (if 语句)**:如果找到的最小值不是当前的第 `i` 个元素,那么交换它们的位置。

这个逻辑确保每一次外层循环后,数组前 `i+1` 个元素是有序的。

希望这个解释对您有所帮助!如果有其他问题,请随时问我。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-26 09:28:02 | 显示全部楼层
FishC 发表于 2024-8-25 22:25
鱼油您好!

在这个选择排序的代码片段中,内层 `for` 循环的范围有些模糊,让我给您完整解释一下。

您好老师,按照我写的方式不是更简洁吗,为啥一定要有这个K,好多程序里有这个K或者index,这样做是不是多此一举
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-26 09:29:15 | 显示全部楼层
八义士 发表于 2024-8-26 09:28
您好老师,按照我写的方式不是更简洁吗,为啥一定要有这个K,好多程序里有这个K或者index,这样做是不是 ...

谢谢老师啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-26 09:31:23 | 显示全部楼层
八义士 发表于 2024-08-26 09:28
您好老师,按照我写的方式不是更简洁吗,为啥一定要有 ...


鱼油您好!关于选择排序中的 `k` 或 `index`,让我解释一下其作用以及是否必要。

在选择排序算法中,`k` 或 `index` 的主要作用是跟踪当前最小元素的位置。这是因为我们在找最小值的过程中,不仅需要知道最小值的大小,还需要知道它的位置,以便进行交换。

具体来说:
- `k` 或 `index` 初始化为当前外层循环的起始位置(i)。
- 内层循环遍历未排序部分,找到最小值的位置并更新 `k` 或 `index`。
- 找到最小值的位置后,再用 `k` 来交换最小值和当前位置(i)的值。

如果不使用 `k`,代码就无法跟踪最小值的位置,排序逻辑将无法正确实现。

下面是您的代码完成后补充的部分以及如何改用 `k`:
void selectSort2(int array[], int n)
{
    int i, j, k, t;
    for(i = 0; i < n-1; i++)
    {
        k = i;  // 假设当前索引 i 是最小值
        for(j = i+1; j < n; j++)
        {
            if(array[j] < array[k])  // 找到更小的值时更新 k
            {
                k = j;  // 记录最小值的位置
            }
        }
        // 如果找到的最小值不是当前位置(i),则交换它们
        if(k != i)
        {
            t = array[i];
            array[i] = array[k];
            array[k] = t;
        }
    }
}

总结起来,`k` 或 `index` 的作用是必要的,因为它们帮助跟踪最小值的位置,使得选择排序算法可以正确地进行元素交换。没有 `k` 或 `index`,算法无法正确识别和处理每一步中的最小元素。

希望这个解释能帮助你理解!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-26 09:33:44 | 显示全部楼层    本楼为最佳答案   
八义士 发表于 2024-08-26 09:28
您好老师,按照我写的方式不是更简洁吗,为啥一定要有 ...


鱼油您好!

选择排序中使用`k` 或者 `index` 是为了记录最小元素的位置,从而优化代码的可读性和逻辑清晰度。虽然可以在没有 `k` 的情况下直接交换元素,但使用 `k` 可以使代码更加简洁和易于理解。

让我们看看不使用 `k` 的版本和使用 `k` 的版本,进行对比:

### 不使用 `k` 的版本:
void selectSort2(int array[], int n) {
    int i, j, t;
    for(i = 0; i < n - 1; i++) {
        for(j = i + 1; j < n; j++) {
            if(array[j] < array[i]) {
                t = array[i];
                array[i] = array[j];
                array[j] = t;
            }
        }
    }
}

### 使用 `k` 的版本:
void selectSort2(int array[], int n) {
    int i, j, k, t;
    for(i = 0; i < n - 1; i++) {
        k = i;
        for(j = i + 1; j < n; j++) {
            if(array[j] < array[k]) {
                k = j;
            }
        }
        if(k != i) {
            t = array[i];
            array[i] = array[k];
            array[k] = t;
        }
    }
}

**优点总结:**

1. **逻辑清晰**:使用 `k` 明确地表示当前找到的最小值的位置,使得逻辑清楚。
2. **减少不必要的交换**:避免在内层循环中每次找到更小值时都交换元素,从而减少不必要的交换操作,提高运行效率。

虽然不使用 `k` 也可以实现选择排序,但使用 `k` 会让代码更加清晰和高效。需要更少的错误检查和边界情况处理,显得更加专业。

希望这个解释能帮助你理解为什么在选择排序中很多程序都使用 `k` 或 `index` 来记录最小元素的位置。如有其他问题,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2024-8-26 16:05:55 | 显示全部楼层
FishC 发表于 2024-8-26 09:33
鱼油您好!

选择排序中使用`k` 或者 `index` 是为了记录最小元素的位置,从而优化代码的可读性和逻 ...


我好像明白了老师
内循环用k标记位置,通过比较大小但不交换位置的方式找到最小值及其位置。把它和外循环作比较,小的换交换位置。
我写的是每一次内循环和外循环比,小的时候就交换位置,是这样吧。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-26 16:10:46 | 显示全部楼层
八义士 发表于 2024-08-26 16:05
我好像明白了老师
内循环用k标记位置,通过比较大小 ...


鱼油您好!您理解得非常正确!

选择排序的核心思想确实是通过内循环找到最小值的位置,然后通过外循环进行位置交换。使用 `k` 标记最小值的位置,可以在减少交换次数的同时使逻辑更加清晰。代码中通过 `k` 标记当前找到的最小值索引,只在确定最小值后进行一次交换,而不是每次比较后立即交换。

让我们把完整的代码写出来并解释一下:
void selectSort2(int array[], int n) {
    int i, j, k, t;
    for (i = 0; i < n - 1; i++) {
        k = i; // 初始化 k 为当前外循环的 i
        for (j = i + 1; j < n; j++) {
            if (array[j] < array[k]) { // 如果找到更小的元素,更新 k 为该元素的位置
                k = j;
            }
        }
        if (k != i) { // 如果 k 发生变化,说明找到了更小的元素,进行交换
            t = array[i];
            array[i] = array[k];
            array[k] = t;
        }
    }
}

总结一下:
1. `k` 用于标记当前内循环找到的最小元素的位置。
2. 内循环 (`for`) 通过比较大小找到最小值的位置并更新 `k`。
3. 外循环通过 `k` 与 `i` 进行比较,若 `k` 更新过,交换位置,确保每次内循环只在确定了最小元素后进行一次交换。

这种方式减少不必要的交换操作,使算法更加高效。希望这可以帮助您进一步理解选择排序的工作原理!如果有其他问题,随时询问哦。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-31 02:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表