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)
总是错误的,您应该改为在(fscanf(in,“%d”,&arr[n])==1{…while(!feof(in))
- 您可能应该分配数组
和arr
,而不是将它们定义为具有自动存储的VLA,以防止在大型输入文件上出现未定义的行为sort\u arr
- 您应该对排序部分使用二进制搜索,否则您的算法的基本复杂度为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