【考研04】排序算法

1. 起泡排序

void BubbleSort(int R[],int n)
{
	int i,j,flag;
	int temp;
	for(i=n-1;i>=1;--i)
	{
		flag = 0;
		for(j=1;j<=i;++j)
		{
			if(R[j-1]>R[j])
			{
				temp = R[j];
				R[j]=R[j-1];
				R[j-1]=temp;
				flag = 1;
			}
		}
		if(flag == 0)  //一趟排序过程中没有发生关键字交换,则证明有序
			return;
	}
}

2. 快速排序

int Partition(int A[],int low,int high)
{
	int pivot = A[low];
	while(low<high)
	{
		while(low<high && A[high] >= pivot)
			--high;
		A[low] = A[high];
		while(low<high && A[low] <= pivot)
			++low;
		A[high] = A[low];
	}
	A[low] = pivot;
	return low;
}
void QuickSort(int A[],int low,int high)
{
	if(low<high)
	{
		int pivotpos = Partition(A,low,high);
		QuickSort(A,low,pivotpos-1);
		QuickSort(A,pivotpos+1,high);
	}
}

3.双向冒泡排序算法

void BubbleSort(int A[],int n)
{  //双向起泡排序,交替进行正反两个方向的起泡过程
	int i,low=0,high=n-1;
	int flag = 1;
	while(low<high && flag == 1)
	{
		flag = 0;
		for(i=low;i<high;i++)  //从前向后起泡
		{
			if(A[i]>A[i+1])  //发生逆序
			{
				swap(A[i],A[i+1]);
				flag = 1;
			}
		}
		high--;
		for(i=high;i>low;i--)  //从后向前起泡
		{
			if(A[i]<A[i-1])  //发生逆序
			{
				swap(A[i],A[i-1]);
				flag = 1;
			}
		}
		low++;
	}
}

4. 已知线性表按顺序存储,且每个元素都是不相同的整数型元素,设计把所有奇数移动到所有偶数前边的算法。

void Move(int A[],int n)
{//对表A按奇偶进行一趟划分
	int i=0,j=n-1;
	while(i<j)
	{
		while(i<j && A[i]%2 == 1) //从前向后找到第一个偶数元素
			i++;
		while(i<j && A[j]%2 == 0) //从后向前找到第一个奇数元素
			j--;
		if(i<j)
		{
			Swap(A[i],A[j]);
			i++;
			j--;
		}
	}
}

5. 试编写一个算法,使之能够在数组L[1…n]中找到第k小的元素(即从小到大排序后处于第k个位置的元素)

int Findk(int a[],int low,int high,int k)
{
	int pivot = a[low];
	int low_temp = low;  //由于下面会修改low与high,在递归时又要用到
	int high_temp = high;
	while(low<high)
	{
		while(low<high && a[high]>=pivot)
			--high;
		a[low] = a[high];
		while(low<high && a[low]<=pivot)
			++low;
		a[high] = a[low];
	}
	a[low]=piovt;
	//上面即为快速排序中的划分算法
	//下面本算法
	if(low == k)
		return a[low];
	else if(low > k)
		return Findk(a,low_temp,low-1,k);
	else
		return Findk(a,low+1,high_temp,k-low);
}

6. 已知由n(n≥2)个正整数构成的集合A={ak|0≤k<n},将其划分为两个不相交的子集A1和A2,元素个数分别是n1和n2,A1和A2中的元素之和分别为S1和S2。设计划分算法,满足|n1-n2|最小且|S1-S2|最大。

int setPartition(int a[],int n)
{
	int pivotkey; //定义枢轴值
	int low=0,low0=0;
	int high=n-1,high0=n-1;
	int flag=1,k=n/2,i;
	int s1=0,s2=0; //划分后两个数组的元素之和
	while(flag == 1)
	{
		pivotkey = a[low]; //选择枢轴
		while(low<high) //基于枢轴对数据进行划分
		{
			while(low<high && a[high]>=pivotkey)
				--high;
			if(low != high)
				a[low] = a[high];
			while(low<high && a[low]<=pivotkey)
				++low;
			if(low != high)
				a[high] = a[low];
		}
		a[low] = pivotkey;
		if(low == k-1); //若枢轴是第n/2小元素,划分成功
			flag = 0;
		else
		{
			if(low < k-1) //若i<n/2,则枢轴及之前的所有元素均属于A1,继续对i之后的
			{			  //元素进行划分
				low0 = ++low; //对后半部分划分
				high = high0; 
			}
			else		  //若i>n/2,则枢轴及之后的所有元素均属于A2,继续对i之前的
			{			  //元素进行划分
				high0 =--high; //对前半部分划分
				low = low0;
			}
		}
	}
	for(i=0;i<k;i++)
		s1 += a[i];
	for(i=k;i<n;i++)
		s2 += a[i];
	return s1-s1;	
}

7. 荷兰国旗

typedef enum
{	RED,
	WHITE,
	BLUE
}color;
void Flag(color a[],int n)
{
	int i=0,j=0,k=n-1;
	while(j <= k)
	{
		switch(a[j])
		{
			case RED: //红色则和i交换
				Swap(a[i],a[j]);
				i++;
				j++;
				break;
			case WHITE:
				j++;
				break;
			case BLUE: //蓝色则和k交换
				Swap(a[j],a[k]);
				k--;  //没有j++语句防止交换后a[j]仍为蓝色的情况
		}
	}
}

8. 归并排序

int *b = (int*)malloc(sizeof(int)*(n+1)); //辅助数组B
void Merge(int a[],int low,int mid,int high)
{
	//表a的两段a[low...mid]和a[mid+1...high]各自有序,将它们合并成一个有序表
	int i,j;
	for(int k=low;k<=high;k++)
		b[k]=a[k]; //将a中所有元素复制到b中
	for(i=low,j=mid+1,k=i;i<=mid && j<=high;k++)
	{
		if(b[i]<=b[j])
			a[k] = b[i++];
		else
			a[k] = b[j++];
	}
	while(i<=mid)
		a[k++] = b[i++];
	while(j<=high)
		a[k++] = b[j++];
}
void MergeSort(int a[],int low,int high)
{
	if(low<high)
	{
		int mid = (low+high)/2;
		MergeSort(A,low,mid);
		MergeSort(A,mid+1,high);
		Merge(A,low,mid,high);
	}
}

9. 堆排序

void Shift(int a[],int low,int high) //关键字存储设定从下标1开始
{
	int i=low,j=2*i;
	int temp = a[i];
	while(j<=high)
	{
		if(j<high && a[j]<a[j+1])
			++j;
		if(temp<a[j])
		{
			a[i] = a[j];
			i = j;
			j = 2*i;
		}
		else
			break;
	}
	a[i] = temp;
}
void heapSort(int a[],int n)
{
	int i;
	int temp;
	for(i=n/2;i>=1;--i)  //建立初始堆
		Shift(a,i,n);
	for(i=n;i>=2;--i)
	{
		temp = a[1];
		a[1]=a[i];
		a[i] = temp;
		Shift(a,1,i-1);
	}
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值