繁体   English   中英

C基本排序算法

[英]C Basic Sort Algorithm

我不太了解使用嵌套For循环的基本排序算法的过程:

for(i=0; i<MAX; i++){
        for(j=i; j<MAX; j++){
            if(data[i] > data[j]){
                tmp = data[i];
                data[i] = data[j];
                data[j] = tmp;
            }
        }
    }

如果j=i那不是就循环并比较相同的数字,因为i和j在循环中都从0开始?

我已经尝试使用Google搜索来对此特定代码进行解释,但找不到任何有用的信息。

完整程序:

#include <stdio.h>
#include <stdlib.h>

#define MAX 10

int main()
{
    int data[MAX];
    int i, j, tmp;

    for(i=0;i<MAX;i++){
        printf("Enter number %d: ", i);
        scanf("%d", &data[i]);
    }

    for(i=0; i<MAX; i++){
        for(j=i; j<MAX; j++){
            if(data[i] > data[j]){
                tmp = data[i];
                data[i] = data[j];
                data[j] = tmp;
            }
        }
    }

    printf("\nSorted List:\n");
    for(i=0;i<MAX;i++){
        printf("Item %d: %d\n", i, data[i]);
    }
}

该算法是一种虚拟化的选择排序 -它与Wikipedia上的选择排序描述相符:

该算法将输入列表分为两部分:已排序项目的子列表,该列表从左到右在列表的前部(左侧)建立;剩下的要排序项目的子列表,它们占据了列表的其余部分。清单。 最初,已排序的子列表为空,未排序的子列表为整个输入列表。 该算法通过在未排序的子列表中找到最小(或最大,取决于排序顺序)元素,将其与最左边的未排序元素交换(交换)(按排序顺序排列),然后将子列表边界向右移动一个元素。

但实际上不是伪算法,因为它会进行一些不必要的交换。

在第一个内部回合中,当i等于j ,比较data[i] > data[j]将为false,并且将不执行交换。

然后, j将递增,现在它正在将i th值与i + 1 th值进行比较。

为了避免徒劳的比较,请使用i + 1初始化j

for (i = 0; i < MAX; i++) {
    for (j = i + 1; j < MAX; j++) {
        if (data[i] > data[j]) {
            tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }
    }
}

它与普通选择排序的不同之处在于,它使从第i个位置来回不必要的交换。 普通选择排序查找最小索引,并且对每个元素仅进行一次交换:

for (i = 0; i < MAX; i++) {
    int min = i;
    for (j = i + 1; j < MAX; j++) {
        if (data[min] > data[j]) {
            min = j;
        }
    }

    tmp = data[min];
    data[min] = data[i];
    data[i] = tmp;
}

但是,原始匹配选择排序的描述(并且运行时间是相同的,尽管常量由于不必要的交换而变得更糟),因为:

该算法通过在未排序子列表中找到最小(或最大,取决于排序顺序)元素,将其与最左边未排序元素交换(交换)(以排序顺序排列)来进行

算法在未排序的子列表中找到最小的元素时,将其实现,当当前最小的项目通过列表时,将其与最左边的未排序的项目交换


C标准库已经包含qsort ,可以使用它代替重新发明轮子-我们只需要编写比较函数即可:

#include <stdlib.h>

int compare_ints(const void *a, const void *b) 
{
    return (*(const int*)a - *(const int*)b);
}

int main(void) {
    ...
    qsort(data, MAX, sizeof(int), compare_ints);
    ...
}

不,它不会循环,因为您只需将data[i]data[i]交换两次,尽管最好像这样重写这段代码:

for(i=0; i<MAX-1; i++){
    for(j=i+1; j<MAX; j++){
        if(data[i] > data[j]){
            tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }
    }
}

但是这两个代码是相同的。

该代码使用的算法是冒泡排序 如果您想更好地了解它的功能,请参阅Wikipedia文章。

这是冒泡排序 其要点是它会交换发现的两个相邻值不按顺序排列,直到所有值都按顺序排列为止。

编码

for(i=0; i<MAX; i++){
        for(j=i; j<MAX; j++){
            if(data[i] > data[j]){
                tmp = data[i];
                data[i] = data[j];
                data[j] = tmp;
            }
        }
    }

显然将无法正常运行。 基本上,它需要比较数组的每个元素并对其进行排序。 基本上是时间复杂度为O(n ^ 2)的冒泡排序。

而不是j = i

应该是j = i + 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM