マージとソートの宿題を書いているときに、多くの再帰を忘れていることに気づきました。
次に、再帰を次のように確認して要約します。
- マージソーティングは、分割して征服するという考え方を使用しています。「分割して征服する」とは、複雑な問題を単純な問題に分割して解決することを意味します。
- 一般的に:分割と征服は複雑な問題を解決するためのアイデアであり、再帰はそれに対する解決策を提供します。
最初に再帰について話しましょう:
- 簡単に言えば、再帰は自分自身を呼び出すことです。再帰的関係とは、エンティティ自体とそれ自体の間の関係の確立です。
- 再帰の条件:
(1)サブ問題は、元の問題と一致し、より単純である必要があります。
(2)再帰には出口が必要です。出口がないと、出てきません。
次に、マージソートを使用して、再帰をより深く理解します。
- マージソートの一般的な考え方は非常に単純です:つまり、最初に分割してからマージします。
2つに分割されるたびに、この分割はいつ終了しますか?
回答:このように考えると、最終的に取得したいのは、並べ替えられた大きな配列です。サブ問題は、並べ替えられた小さな配列を取得することです。小さな配列はいつ順序付けられますか?配列に要素が1つしかない場合、次に、小さな配列が注文されます。このようにして、low <highの再帰条件を取得します。
上の直接の写真:
実は私もその時でした。先生も授業で教えられた考えをすべて理解していましたが、それでも彼がどのように順番に融合したのかよくわかりませんでした。これは私の繰り返しの忘れに対する批判でもあります。
私が書いたコードMERGEは、2つの小さな配列をマージしてソートします。(背後にコードがあります)
実際、再帰的な手順を理解するのは簡単です。上の図に
進んでください:↑
コード↓
#include <stdio.h>
#include <stdlib.h>
#define N 1000000
void Mergesort(int *A,int low,int high,int *temp)
{
if(low < high)
{
int mid = (high+low)/2;
Mergesort(A,low,mid,temp);
Mergesort(A,mid+1,high,temp);
MERGE(A,low,mid,high,temp);
}
}
void MERGE(int *A,int low,int mid,int high,int *temp)
{
int i=low;int j=mid;
int m=mid+1;int n=high;
int k=0;
//开始合并两个数组;
while(i <= j && m <= n)
{
if(A[i] <= A[m])
{
temp[k++] = A[i++];
}
else
{
temp[k++] = A[m++];
}
}
while(i <= j)
{
temp[k++] = A[i++];
}
while(m <= n)
{
temp[k++] = A[m++];
}
//把temp数组中的结果装回A数组
for(i = 0; i < k; i++)
{
A[i+low] = temp[i];
}
}
int main(int argc, const char * argv[])
{
int i,j;
int num[100000];
int temp[100000];
FILE* fp = fopen("1.txt","r");//读文件
FILE* stream = fopen("2.txt","w");//向文件中写入
if(fp==NULL)
{
printf("没找到文件");
return 0;
}
for(i=0;i<100000;i++)
{
fscanf(fp,"%d",&num[i]);
}
fclose(fp);
Mergesort(num,0,99999,temp);
for(j=0;j<100000;j++)
{
fprintf(stream,"%d\n",num[j]);
}
fclose(stream);
return 0;
}
仕事に必要なため、私のコードにはtxtファイルの読み取りおよび書き込み操作があります(✿◡‿◡)。