Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 双向插入排序不排序_C_Sorting - Fatal编程技术网

C 双向插入排序不排序

C 双向插入排序不排序,c,sorting,C,Sorting,这应该是双向插入排序,但不是排序。我还应该打印出作业的数量进行排序,但现在我只想让它进行排序 留出一个大小为2n+1的单独输出数组。最初x[0]被放置在数组n的中间元素中。 继续插入元素,直到需要在数组中的一对元素之间插入为止。 和以前一样,您需要通过移动元素为新元素腾出空间。不像以前,, 您可以选择将所有较小的图元向左移动一步,或将所有较大的图元向左移动一步 因为阵列的两侧都有额外的空间,所以在右侧。选择哪一个 要执行的移位取决于需要移位的元素最少 我在网上找不到太多关于这类的东西,只是没人用

这应该是双向插入排序,但不是排序。我还应该打印出作业的数量进行排序,但现在我只想让它进行排序

留出一个大小为
2n+1
的单独输出数组。最初
x[0]
被放置在数组
n
的中间元素中。 继续插入元素,直到需要在数组中的一对元素之间插入为止。 和以前一样,您需要通过移动元素为新元素腾出空间。不像以前,, 您可以选择将所有较小的图元向左移动一步,或将所有较大的图元向左移动一步 因为阵列的两侧都有额外的空间,所以在右侧。选择哪一个 要执行的移位取决于需要移位的元素最少

我在网上找不到太多关于这类的东西,只是没人用

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

void printArray(int arr[], int len) {
    for (int j = 0; j < len; j++)
        printf("%d ", arr[j]);

    printf("\n");
}

int main() {
    FILE *in;
    int size_arr = 0;
    char ch;

    if ((in = fopen("data_a5.txt", "r")) == NULL) {
        printf("Error!");
        exit(1);
    }
    do {
        ch = fgetc(in);
        if (ch == '\n')
            size_arr++;
    } while (ch != EOF);
    rewind(in);

    int arr[size_arr];
    int sort_arr[2 * size_arr + 1];

    int n = 0;
    while (!feof(in)) {
        fscanf(in, "%d", &arr[n]);
        n++;
    }
    fclose(in);

    for (n = 0; n < 2 * size_arr; n++) {
        sort_arr[n] = 0;
    }

    sort_arr[size_arr] = arr[0];

    for (n = 1; n < size_arr; n++) {
        int index = size_arr;
        if (arr[n] <= sort_arr[size_arr]) {
            while (!(arr[n] <= sort_arr[index]) && sort_arr[index] != 0 && index >= 0) {
                index--;
            }
        }
        if (arr[n] > sort_arr[size_arr]) {
            while (!(arr[n] <= sort_arr[index]) && sort_arr[index] != 0 && index < 2 * size_arr) {
                index++;
            }
        }

        if (sort_arr[index] == 0) {
            sort_arr[index] = arr[n];
        } else {
            int next_R, next_L = index;
            while (sort_arr[next_R] != 0 && next_R <= 2 * size_arr) {
                next_R++;
            }
            while (sort_arr[next_L] != 0 && next_L >= 0) {
                next_L--;
            }
            int R_move = next_R - index;
            int L_move = index - next_L;
            if (R_move > L_move) {
                while (L_move <= index) {
                    sort_arr[L_move] = sort_arr[L_move + 1];
                    L_move++;
                }
                sort_arr[index] = arr[n];
            } else {
                while (R_move >= index) {
                    sort_arr[R_move] = sort_arr[R_move - 1];
                    R_move--;
                }
                sort_arr[index] = arr[n];
            }
        }
    }
    printArray(arr, size_arr);
    return 0;
}
#包括
#包括
#包括
无效打印数组(int arr[],int len){
对于(int j=0;j
我不确定这能解决所有问题,但这是一个您必须解决的问题

此代码

    int next_R, next_L = index;
    while(sort_arr[next_R] != 0 && next_R <= 2*size_arr)
在任何情况下,您都必须在使用它之前初始化
next\R

我也觉得这句话很奇怪:

printArray(arr, size_arr);
           ^^^
似乎您正在打印原始数组,而不是已排序的数组

可能是你想要的:

    int next_R = index, next_L = index;
                 ^^^^^
    while(sort_arr[next_R] != 0 && next_R <= 2*size_arr)
printArray(sort_arr, size_arr);
           ^^^^^
像这样

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

void printArray(int arr[], int len){
    while(len--)
        printf("%d ", *arr++);
    printf("\n");
}

int main(void){
    int size_arr = 10;
    int arr[size_arr];
    int sort_arr[2 * size_arr + 1];

    for(int i = 0; i < size_arr; ++i)
        arr[i] = -50 + rand() % (100 + 1);
    puts("before:");
    printArray(arr, size_arr);

    int left, right;
    sort_arr[left = right = size_arr] = arr[0];

    for (int n = 1; n < size_arr; ++n){
        int v = arr[n];
        if(v <= sort_arr[left]){
            sort_arr[--left] = v;
        } else if(v >= sort_arr[right]){
            sort_arr[++right] = v;
        } else {
            int L = left, R = right, M, MV;
            while(L <= R){
                M = L + (R-L)/2;
                MV = sort_arr[M];
                if(MV < v)
                    L = M + 1;
                else if(v < MV)
                    R = M - 1;
                else
                    break;
            }
            //M: insert position
            enum { LEFT, RIGHT } CHOICE;
            if(v == MV){
                int ML = M, MR = M;
                while(sort_arr[ML-1] == sort_arr[ML])
                    --ML;
                while(sort_arr[MR] == sort_arr[MR+1])
                    ++MR;
                if( ML-left >= right-MR){
                    M = MR+1;
                    CHOICE = RIGHT;
                } else {
                    M = ML;
                    CHOICE = LEFT;
                }
            } else if(v > MV){
                ++M;
                CHOICE = M-left+1 > right-M;// ? RIGHT : LEFT;
            } else {
                CHOICE = M-left-1 > right-M;// ? RIGHT : LEFT;
            }
            if(CHOICE == RIGHT){
                memmove(sort_arr + M+1, sort_arr + M, (right-M+1)*sizeof(v));
                sort_arr[M] = v;
                ++right;
            } else {
                memmove(sort_arr + left-1, sort_arr + left, (M-left)*sizeof(v));
                sort_arr[M-1] = v;
                --left;
            }
        }
    }
    puts("after:");
    printArray(sort_arr + left, size_arr);
    return 0;
}
#包括
#包括
#包括
无效打印数组(int arr[],int len){
而(len--)
printf(“%d”,*arr++);
printf(“\n”);
}
内部主(空){
int size_arr=10;
int arr[大小arr];
int sort_arr[2*size_arr+1];
对于(int i=0;iMV){
++M;
选项=M-left+1>right-M;//?right:left;
}否则{
CHOICE=M-left-1>right-M;//?right:left;
}
如果(选项==右){
memmove(sort_arr+M+1,sort_arr+M,(右-M+1)*sizeof(v));
排序arr[M]=v;
++对,;
}否则{
memmove(sort_arr+left-1,sort_arr+left,(M-left)*sizeof(v));
排序arr[M-1]=v;
--左;
}
}
}
放(在:)之后;
打印数组(排序数组+左,大小数组);
返回0;
}

您的代码中存在一些问题:

  • 在第一次扫描文件时,应该计算整数的数量,而不是字符的数量

  • 插入时,循环关闭一次:测试应读取
    while(L\u move
    while(R\u move>=index)

  • while(!feof(in))
    总是错误的,您应该改为在(fscanf(in,“%d”,&arr[n])==1{…

  • 您可能应该分配数组
    arr
    sort\u arr
    ,而不是将它们定义为具有自动存储的VLA,以防止在大型输入文件上出现未定义的行为

  • 您应该对排序部分使用二进制搜索,否则您的算法的基本复杂度为O(N2),这使插入阶段最小化所获得的小增益相形见绌

代码如下:

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

void print_array(const int arr[], int len) {
    for (int j = 0; j < len; j++)
        printf("%d%c", arr[j], " \n"[j == len - 1]);
}

int main(void) {
    FILE *in;
    int size_arr, n, start;
    int value;

    if ((in = fopen("data_a5.txt", "r")) == NULL) {
        printf("Cannot open input file %s\n", "data_a5.txt");
        exit(1);
    }
    for (size_arr = 0; fscanf(in, "%d", &value) == 1; size_arr++)
        continue;

    rewind(in);

    int *arr = calloc(2 * size_arr + 1, sizeof(*arr));
    if (arr == NULL) {
        printf("Cannot allocate memory for %d entries\n", size_arr);
        exit(1);
    }

    start = size_arr;
    for (n = 0; n < size_arr && fscanf(in, "%d", &value) == 1; n++) {
        /* insert value into the sorted array */
        int a, b;
        for (a = start, b = start + n; a < b;) {
            int mid = a + (b - a) / 2;
            if (arr[mid] < value) {
                a = mid + 1;
            } else {
                b = mid;
            }
        }
        /* insert value at offset b */
        if (b - start < start + n - b) {
            /* shift left portion to the left */
            for (int i = start--; i < b; i++) {
                arr[i - 1] = arr[i];
            }
            b--;
        } else {
            /* shift right portion to the right */
            for (int i = start + n + 1; --i > b;) {
                arr[i] = arr[i - 1];
            }
        }
        arr[b] = value;
    }
    fclose(in);

    print_array(arr + start, n);
    free(arr);
    return 0;
}
#包括
#包括
无效打印数组(常量int arr[],int len){
对于(int j=0;j