//分两层理解快排和归并排序:
//1 递归 如何把数组一分为二
//终止条件:left == right
//递归的参数:快排是根据重叠后的i和j一分为二,归并是根据mid,
//2 操作 归并时merge 快速是向左向右走
//merge
//[i] [j]比较大小 满足的赋值给[k++] 自己也++
//等有一个走到头,再把剩下的全赋值给[k]
//向左向右
//j一直向左,满足条件就交换,结束循环
//i一直向右,满足条件就交换,结束循环
//1 递归 如何把数组一分为二
//终止条件:left == right
//递归的参数:快排是根据重叠后的i和j一分为二,归并是根据mid,
//2 操作 归并时merge 快速是向左向右走
//merge
//[i] [j]比较大小 满足的赋值给[k++] 自己也++
//等有一个走到头,再把剩下的全赋值给[k]
//向左向右
//j一直向左,满足条件就交换,结束循环
//i一直向右,满足条件就交换,结束循环
//等i,j重叠时,结束,把key放回来到重叠的位置
快速排序:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void sort_quick(int *a, int left, int right)
{
int i = 0, j = 0, key = 0;
//1 如果left与right重叠,已经完成排序,返回
if (left >= right)
{
return;
}
//2 选key,i为左,j为右
key = a[left];
i = left;
j = right;
//3 如果i,j重叠,完成了本轮排序,请记得把key放回来 4 5循环体
while (i < j)
{
//4 从右向左,i<j或key<=a[j],一直让j--,退出循环后让a[i] = a[j]
//a[i]原本为空
while ( (i < j )&& (key <= a[j]) )
{
j--;
}
a[i] = a[j];
//5 从左向右,i<j或key>=a[i],一直让i++,退出循环后让a[j] = a[i]
//a[j]为空
while ( (i < j) && (key >= a[i]) )
{
i++;
}
a[j] = a[i];
}
a[i] = key; //此时i==j
//6 递归地调用
sort_quick(a, left, i - 1);
sort_quick(a, i + 1, right);
}
void main0402()
{
int i = 0;
int a[11] = { 5, 3, 9, 0 ,12,66,78,24,2,4,88 };
sort_quick(a, 0, 10);
for (i = 0; i < 11; ++i)
{
printf("%d ", a[i]);
}
system("pause");
}
//1 如果left>=right说明已经完成排序
//2 给key=a[left],i = left, j = right
//3 while(i<j)就说明本轮没有完成,完成后记得把key放回来
//4 向左走 while( i<j && key<= a[j]) j--;
//a[i] = a[j]
//5 向右走 while( i<j && a[i] <= key i++;
//a[j] = a[i]
//6 把key放回去
//7 递归调用
归并:
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
//1
void merge(int *sourceArray, int *tempArray, int left, int mid, int right)
{
int i = left;
int j = mid + 1;
int k = left;
//只要没有走到头 走到头了 判断是谁到头 另一个全抄下去
while (i != mid+1 && j != right+1)
{
//比较[i] <= [j] 就 [k++] = [i++]
//else [k++] = [j++]
if (sourceArray[i] <= sourceArray[j])
{
tempArray[k++] = sourceArray[i++];
}
else
{
tempArray[k++] = sourceArray[j++];
}
}
//判断 如果没到头 全抄
while (i != mid+1)
{
tempArray[k++] = sourceArray[i++];
}
while (j != right+1)
{
tempArray[k++] = sourceArray[j++];
}
//把temp的元素移动到source中
for (k = left; k <= right; ++k)
{
sourceArray[k] = tempArray[k];
}
}
//2 递归地调用
void sort_merge(int *sourceArray, int *tempArray, int left, int right)
{
int mid = 0;
//1 left==right说明已经分到了1个元素为一组 返回
if (left == right)
{
return;
}
mid = (left + right) / 2;
//mid = (left + right) / 2
sort_merge(sourceArray, tempArray, left, mid);
sort_merge(sourceArray, tempArray, mid + 1, right);
//3 merge
merge(sourceArray, tempArray, left, mid, right);
}
int main(int argc, char * argv[])
{
int a[8] = { 50, 10, 20, 30, 70, 40, 80, 60 };
int i, b[8];
sort_merge(a, b, 0, 7);
for (i = 0; i<8; i++)
printf("%d ", a[i]);
printf("\n");
system("pause");
return 0;
}
//1 merge()的功能:将一个分成两截的有序序列合并为一个有序序列
//参数:source[] temp[] left mid right
//2 给i=left,j=mid+1,k=left初始值
//2 都没有走到头,当i!=mid+1 && j!=right+1时,比较[i][j]的大小,分情况赋值给[k++],自己也++
//3 有一个走到头结束循环后,while i!=mid+1) while(j!=right+1)把剩下的都粘贴给temp
//4 把元素从temp中移动回来
//2 递归地调用merge():
//1 递归结束的判断:如果left==right说明已经分成一个元素了 返回
//1 mid = =