各类常用排序算法的总结

void selectSort()
{
	for (int i = 1; i <= n; i++)//进行n趟操作
	{
		int k = i;
		for (int j = i; j <= n; j++)//选出[i,n]中最小的元素,下标为k
		{
			if (A[j] < A[k])
			{
				k = j;
			}
		}
		int temp = A[i];//交换A[k]与A[i]
		A[i] = A[k];
		A[k] = temp;
	}
}//选择排序
//*************************************************************************************
int A[maxn], n;//n为元素个数,数组下标为1~n
void insertSort()
{
	for (int i = 2; i <= n; i++)//进行n-1趟排序
	{
		int temp = A[i], j = i;//temp临时存放A[i],j从i开始往前枚举
		while (j > 1 && temp < A[j - 1])//只要temp小于前一个元素A[j-1]
		{
			A[j] = A[j - 1];//把A[j-1]后移一位至A[j]
			j--;
		}
		A[j] = temp;//插入位置为j
	}
}//插入排序
 //*************************************************************************************
const int maxn = 100;
//将数组A的[L1,R1]与[L2,R2]区间合并为有序区间(此处L2即为R1+1)
void merge(int A[], int L1, int R1, int L2, int R2)
{
	int i = L1, j = L2;//i指向A[L1],j指向A[L2]
	int temp[maxn], index = 0;//temp临时存放合并后的数组,index为其下标
	while (i <= R1&&j <= R2)
	{
		if (A[i] <= A[j])//如果A[i]<=A[j]
		{
			temp[index++] = A[i++];//将A[i]加入序列temp
		}
		else//如果A[i]>A[j]
		{
			temp[index++] = A[j++];//将A[j]加入序列temp
		}
	}
	while (i <= R1)temp[index++] = A[i++];//将[L1,R1]的剩余元素加入序列temp
	while (j <= R2)temp[index++] = A[j++];//将[L2,R2]的剩余元素加入序列temp
	for (i = 0; i < index; i++)
	{
		A[L1 + i] = temp[i];//将合并后的序列赋值回数组A
	}
}
//将array数组当前区间[left,right]进行归并排序
void mergeSort(int A[], int left, int right)
{
	if (left < right)
	{
		int mid = (left + right) / 2;//取[left,right]的中点
		mergeSort(A, left, mid);//递归,将左子区间[left,mid]归并排序
		mergeSort(A, mid + 1, right);//递归,将右子区间[mid+1,right]归并排序
		merge(A, left, mid, mid + 1, right);//将左子区间和右子区间合并
	}
}//递归实现二路-归并排序
 //*************************************************************************************
void mergeSort(int A[])
{
	//step为组内元素个数,step/2为左子区间元素个数,注意等号可以不取
	for (int step = 2; step / 2 <= n; step *= 2)
	{
		//每step个元素一组,组内前step/2和后step/2个元素进行合并
		for (int i = 1; i <= n; i+=step)//对每一组
		{
			int mid = i + step / 2 - 1;//左子区间元素个数为step/2
			if (mid + 1 <= n)//右子区间存在元素则合并
			{
				//左子区间为[i,mid],右子区间为[mid+1,min(i+step-1,n)]
				merge(A, i, mid, mid + 1, min(i + step - 1, n));
			}
		}
	}
}
void mergeSort(int A[])
{
	//step为组内元素个数,step/2为左子区间元素个数,注意等号可以不取
	for (int step = 2; step / 2 <= n; step *= 2)
	{
		//每step个元素一组,组内[i,min(i+step,n+1)]进行排序
		for (int i = 1; i <= n; i+=step)
		{
			sort(A + i, A + min(i + step, n + 1));//可代替merge
		}
	}
	//此处可以输出归并排序的某一趟结束的序列
}//非递归实现二路-归并排序
 //*************************************************************************************
int Partition(int A[], int left, int right)
{
	int p = (round(1.0*rand() / RAND_MAX*(right - left)) + left);
	swap(A[p], A[left]);
	//以上两句是为了随机选取主元
	int temp = A[left];//将A[left]存放至临时变量temp
	while (left < right)//只要left与right不相遇
	{
		while (left<right&&A[right]>temp)right--;//反复左移right
		A[left] = A[right];//将A[right]挪到A[left]
		while (left < right&&A[left] <= temp)left++;//反复右移left
		A[right] = A[left];//将A[left]挪到A[right]
	}
	A[left] = temp;//把temp放到left与right相遇的地方
	return left;//返回相遇的下标
}
void quickSort(int A[], int left, int right)
{//快速排序,left与right初值为序列首尾下标
	if (left < right)//当前区间的长度不超过1
	{//将[left,right]按A[left]一分为2
		int pos = Partition(A,left,right);
		quickSort(A, left, pos - 1);//对左子区间递归进行快速排序
		quickSort(A, pos + 1, right);//对右子区间递归进行快速排序

	}
}//快速排序
 //*************************************************************************************
const int maxn = 100;
//heap为堆,n为元素个数
int heap[maxn], n = 10;
//对heap数组在[low,high]范围进行向下调整
//其中low为欲调整结点的数组下标,high一般为堆的最后一个元素的数组下标
void downAdjust(int low, int high)
{
	int i = low, j = i * 2;//i为欲调整结点,j为其左孩子
	while (j <= high)//存在孩子结点
	{//如果右孩子存在,且右孩子的值大于左孩子
		if (j + 1 <= high&&heap[j + 1] > heap[j])
		{
			j = j + 1;//让j存储右孩子下标
		}
		//如果孩子中最大的权值比欲调整结点i大
		if (heap[j] > heap[i])
		{
			swap(heap[j], heap[i]);//交换最大权值的孩子与欲调整结点i
			i = j;//保持i为欲调整结点、j为i的左孩子
			j = i * 2;
		}
		else
		{
			break;//孩子的权值均比欲调整结点i小,调整结束
		}
	}
}
void createHeap()//建堆
{
	for (int i = n / 2; i >= 1; i--)
	{
		downAdjust(i, n);
	}
}
void deleteTop()//删除堆顶元素
{
	heap[1] = heap[n--];//用最后一个元素覆盖堆顶元素,并让元素个数减1
	downAdjust(1, n);//向下调整堆顶元素
}
//对heap数组在[low,high]范围进行向上调整
//其中low一般设置为1,high表示欲调整结点的数组下标
void upAdjust(int low, int high)
{
	int i = high, j = i / 2;//i为欲调整结点,j为其父亲
	while (j >= low)//父亲在[low,high]范围内
	{//父亲权值小于欲调整结点i的权值
		if (heap[j] < heap[i])
		{
			swap(heap[j], heap[i]);//交换父亲和欲调整结点
			i = j;
			j = i / 2;
		}
		else
		{
			break;//父亲权值比欲调整结点i的权值大,调整结束
		}
	}
}
void insert(int x)
{
	heap[++n] = x;//让元素个数加1,然后将数组末位赋值为x
	upAdjust(1, n);//向上调整新加入的节点n
}
void heapSort()
{
	createHeap();//建堆
	for (int i = n; i > 1; i--)//倒着枚举,直到堆中只有一个元素
	{
		swap(heap[1], heap[i]);//交换heap[i]与堆顶
		downAdjust(1, i - 1);//调整堆顶
	}
}
//堆排序
//*************************************************************************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值