简体   繁体   English

C基本排序算法

[英]C Basic Sort Algorithm

I'm not really understanding the process behind this basic sorting algorithm using nested For loops: 我不太了解使用嵌套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;
            }
        }
    }

If j=i then wouldn't it just be looping and comparing the same numbers seeing as i and j both start at 0 in the loops? 如果j=i那不是就循环并比较相同的数字,因为i和j在循环中都从0开始?

I've tried googling for an explanation on this particular bit of code and can't find anything useful. 我已经尝试使用Google搜索来对此特定代码进行解释,但找不到任何有用的信息。

Full program: 完整程序:

#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]);
    }
}

This algorithm is a dummified selection sort - it matches the description of selection sort on Wikipedia: 该算法是一种虚拟化的选择排序 -它与Wikipedia上的选择排序描述相符:

The algorithm divides the input list into two parts: the sublist of items already sorted, which is built up from left to right at the front (left) of the list, and the sublist of items remaining to be sorted that occupy the rest of the list. 该算法将输入列表分为两部分:已排序项目的子列表,该列表从左到右在列表的前部(左侧)建立;剩下的要排序项目的子列表,它们占据了列表的其余部分。清单。 Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. 最初,已排序的子列表为空,未排序的子列表为整个输入列表。 The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist, exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order), and moving the sublist boundaries one element to the right. 该算法通过在未排序的子列表中找到最小(或最大,取决于排序顺序)元素,将其与最左边的未排序元素交换(交换)(按排序顺序排列),然后将子列表边界向右移动一个元素。

But indeed not the pseudo algorithm in that it does some unnecessary swaps. 但实际上不是伪算法,因为它会进行一些不必要的交换。

In the first inner round, with i being equal to j , the comparison data[i] > data[j] will be false, and the swap will not be executed. 在第一个内部回合中,当i等于j ,比较data[i] > data[j]将为false,并且将不执行交换。

Then, j will be incremented, and now it is comparing i th value with i + 1 th value. 然后, j将递增,现在它正在将i th值与i + 1 th值进行比较。

To avoid one futile comparison, initialize j with i + 1 : 为了避免徒劳的比较,请使用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;
        }
    }
}

What it does different from ordinary selection sort is that it makes unnecessary swaps back and forth from the i th place. 它与普通选择排序的不同之处在于,它使从第i个位置来回不必要的交换。 The ordinary selection sort finds the minimum index and does only one swap for each element: 普通选择排序查找最小索引,并且对每个元素仅进行一次交换:

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;
}

Nevertheless, the original matches the description of selection sort (and the running time is the same, though constants are worse due to unnecessary swapping) in that: 但是,原始匹配选择排序的描述(并且运行时间是相同的,尽管常量由于不必要的交换而变得更糟),因为:

The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist, exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order) 该算法通过在未排序子列表中找到最小(或最大,取决于排序顺序)元素,将其与最左边未排序元素交换(交换)(以排序顺序排列)来进行

is realized as the algorithm finds the smallest element in the unsorted sublist, exchanging the current smallest item with the leftmost unsorted item as it goes over the list . 算法在未排序的子列表中找到最小的元素时,将其实现,当当前最小的项目通过列表时,将其与最左边的未排序的项目交换


The C standard library already contains qsort which can be used instead of reinventing the wheel - we just need to write the comparison function: 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);
    ...
}

No it wouldn't loop because you'll just swap the data[i] with data[i] twice although it is better to rewrite this piece of code like this : 不,它不会循环,因为您只需将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;
        }
    }
}

but this two code are same. 但是这两个代码是相同的。

the algorithm that this codes are using is bubble sort . 该代码使用的算法是冒泡排序 If you want to have better understanding of what it does take a look at the wikipedia article. 如果您想更好地了解它的功能,请参阅Wikipedia文章。

This is a Bubble Sort . 这是冒泡排序 The gist of it is that it swaps any two adjacent values that it finds out of order, until all of the values are in order. 其要点是它会交换发现的两个相邻值不按顺序排列,直到所有值都按顺序排列为止。

The code 编码

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;
            }
        }
    }

Will clearly not work as it is supposed to. 显然将无法正常运行。 It basically needs to compare each and every element of the array and sorts them. 基本上,它需要比较数组的每个元素并对其进行排序。 Basically a bubble sort with time complexity O(n^2). 基本上是时间复杂度为O(n ^ 2)的冒泡排序。

Rather than j=i 而不是j = i

It should be j=i+1 应该是j = i + 1

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

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