排序--快排和归并

//分两层理解快排和归并排序:
//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 = =


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值