一些排序的代码

记一下

#include <iostream>
#include <stdio.h>    
#include <string.h>
#include <ctype.h>      
#include <stdlib.h>   
#include <io.h>  
#include <math.h>  
#include <time.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAX_LENGTH_INSERT_SORT 7 /* 用于快速排序时判断是否选用插入排序阙值 */

typedef int Status;


#define MAXSIZE 10000  /* 用于要排序数组个数最大值,可根据需要修改 */
typedef struct {
	int r[MAXSIZE + 1];	/* 用于存储要排序数组,r[0]用作哨兵或临时变量 */
	int length;			/* 用于记录顺序表的长度 */
}SqList;

/* 交换L中数组r的下标为i和j的值 */
void swap(SqList *L, int i, int j) {
	int temp = L->r[i];
	L->r[i] = L->r[j];
	L->r[j] = temp;
}
#pragma region 交换
//低端冒泡_从前往后 一个个位置排,找小的上来,大的下去
void BubbleSort0(SqList *L) {
	int i, j;
	for (i = 1; i < L->length; i++) {//这里把0当哨兵
		for (j = i + 1; j <= L->length; j++) {//和现在位置之后的每个比
			if (L->r[i] > L->r[j]) {//后面的小?换到现在的位置
				swap(L, i, j);
			}
		}
	}
}
//普通冒泡_从后往前,对比邻居,小的会一点点浮上来 大的下去同理,j 1到length-i
void BubbleSort(SqList *L) {
	int i, j;
	for (i = 1; i < L->length; i++) {
		for (j = L->length - 1; j >= i; j--) {
			if (L->r[j] > L->r[j + 1]) {
				swap(L, j, j + 1);
			}
		}
	}
}
//优化冒泡_没有数据交换,flag不变成true,说明已经有序 可以结束
void BubbleSort2(SqList *L) {
	int i, j;
	Status flag = TRUE;
	for (i = 1; i < L->length&&flag; i++) {
		flag = FALSE;
		for (j = L->length - 1; j >= i; j--) {
			if (L->r[j] > L->r[j + 1]) {
				swap(L, j, j + 1);
				flag = TRUE;
			}
		}
	}
}
/********************************************/
void QSort(SqList *L, int low, int high);
int Paritition(SqList *L, int low, int high);
//快速排序
void QuickSort(SqList *L) {
	QSort(L, 1, L->length);
}
void QSort(SqList *L, int low, int high) {
	int pivot;
	if (low < high) {
		pivot = Paritition(L, low, high);
		QSort(L, low, pivot - 1);
		QSort(L, pivot + 1, high);
	}
}
int Paritition(SqList *L, int low, int high) {
	int pivotkey;
	pivotkey = L->r[low];//用low的时候,下面先从high往左;用high,下面先从low往右
	while (low < high) {
		while (low < high&&pivotkey <= L->r[high])//右边更大,通过检验
			high--;//下一个。
		swap(L, low, high);//每次循环最多查一个更大的换右边去
		while (low < high&&pivotkey >= L->r[low])
			low++;
		swap(L, low, high);//每次循环最多查一个更小的换左边去
	}
	return low;
}
/* 改进后快速排序******************************** */

/* 快速排序优化算法 */
int Partition1(SqList *L, int low, int high) {
	int pivotkey;

	int m = low + (high - low) / 2; /* 计算数组中间的元素的下标 */					/*new*/
	if (L->r[low] > L->r[high])
		swap(L, low, high);	/* 交换左端与右端数据,保证左端较小 */					/*new*/
	if (L->r[m] > L->r[high])
		swap(L, high, m);		/* 交换中间与右端数据,保证中间较小 */				/*new*/
	if (L->r[m] > L->r[low])
		swap(L, m, low);		/* 交换中间与左端数据,保证左端较小 */				/*new*/

	pivotkey = L->r[low]; /* 用子表的第一个记录作枢轴记录 */
	L->r[0] = pivotkey;  /* 将枢轴关键字备份到L->r[0] */							/*new*/
	while (low < high) /*  从表的两端交替地向中间扫描 */
	{
		while (low < high&&L->r[high] >= pivotkey)
			high--;
		L->r[low] = L->r[high];													/*new*/
		while (low < high&&L->r[low] <= pivotkey)
			low++;
		L->r[high] = L->r[low];													/*new*/
	}
	L->r[low] = L->r[0];														/*new*/
	return low; /* 返回枢轴所在位置 */
}

void QSort1(SqList *L, int low, int high) {
	int pivot;
	if ((high - low) > MAX_LENGTH_INSERT_SORT) {								/*new*/
		while (low < high) {													/*new*/
			pivot = Partition1(L, low, high); /*  将L->r[low..high]一分为二,算出枢轴值pivot */
			QSort1(L, low, pivot - 1);		/*  对低子表递归排序 */
			/* QSort(L,pivot+1,high);		/*  对高子表递归排序 */
			low = pivot + 1;	/* 尾递归 */										/*new*/
		}
	} else
		InsertSort(L);//快排要用到递归,在小数组时,大炮打蚊子也许不如简单排序中性能最好的直接插入
}

/* 对顺序表L作快速排序 */
void QuickSort1(SqList *L) {
	QSort1(L, 1, L->length);
}
#pragma endregion
#pragma region 选择
//简单选择_单次循环里选一个最小的,换到当前位置
void SelectSort(SqList *L) {
	int i, j, min;
	for (i = 1; i < L->length; i++) {
		min = i;
		for (j = i + 1; j <= L->length; j++) {
			if (L->r[min] > L->r[j])
				min = j;
		}
		if (i != min)
			swap(L, i, min);
	}
}
/********************************************/
void HeapAdjust(SqList *L, int s, int m);//s是顶部,m是下限
//堆排序
void HeapSort(SqList *L) {
	int i;
	for (i = L->length / 2; i > 0; i--)
		HeapAdjust(L, i, L->length);
	for (i = L->length; i > 1; i--) {
		swap(L, 1, i);//最大放到<当前>最后
		HeapAdjust(L, 1, i - 1);//第一个不是最大了,重新调
	}
}
void HeapAdjust(SqList *L, int s, int m) {//s是顶部,m是下限
	int temp, j;
	temp = L->r[s];
	for (j = 2 * s; j <= m; j *= 2) {//子是2i和2i+1
		if (j < m&&L->r[j] < L->r[j + 1])
			j++;
		if (temp >= L->r[j]) //下沉到没刚才的顶小为止
			break;
		L->r[s] = L->r[j];
		s = j;//值上去,s顶部标记继续往下走
	}
	L->r[s] = temp;
}
#pragma endregion
#pragma region 插入
//直接插入
void InsertSort(SqList *L) {
	int i, j;
	for (i = 2; i <= L->length; i++) {//选要处理的值
		if (L->r[i] < L->r[i - 1]) {//比前面的小
			L->r[0] = L->r[i];		//设置哨兵
			for (j = i - 1; L->r[j] > L->r[0]; j--)//如果比待处理的值大
				L->r[j + 1] = L->r[j];//移到后面
			L->r[j + 1] = L->r[0];//j--后退出了循环,j+1位移动到了j+2位置,j+1正空缺
		}
	}
}
void BinaryInsertSort(SqList *L) {
	int i, j;
	int low, high, mid;
	for (i = 2; i <= L->length; i++) {//选要处理的值
		L->r[0] = L->r[i];
		low = 1;
		high = i - 1;
		while (low <= high) {
			mid = (low + high) / 2;
			if (L->r[mid] > L->r[0])
				high = mid - 1;//比待处理还大,继续找
			else low = mid + 1;
		}
		for (j = i - 1; j >= high + 1; j--)
			L->r[j + 1] = L->r[j];
		L->r[high + 1] = L->r[0];
	}
}
/********************************************/
//希尔排序
void ShellSort(SqList *L) {
	int i, j;
	int increment = L->length;
	do {
		increment = increment / 3 + 1;
		for (i = increment + 1; i <= L->length; i++) {
			if (L->r[i] < L->r[i - increment]) {//反着来!以增量后面的i为标杆
				L->r[0] = L->r[i];
				for (j = i - increment; j > 0 && L->r[0] < L->r[j]; j -= increment) //这边是移动
					L->r[j + increment] = L->r[j];//把j放到后面 第一波是i-cre放到i,第二波是更前面的后移
				L->r[j + increment] = L->r[0];//这时候j是小于0,加回increment,到队列中的刚才位置
			}
		}
	} while (increment > 1);
}
#pragma endregion
#pragma region 归并
void Merge(int SR[], int TR[], int low, int mid, int high);
void MSort(int SR[], int TR1[], int low, int high);
//二路归并
void MergeSort(SqList* L) {
	MSort(L->r, L->r, 1, L->length);
}
void MSort(int SR[], int TR1[], int low, int high) {
	int mid;
	int TR2[MAXSIZE + 1];
	if (low == high) TR1[low] = SR[low];
	else {
		mid = (low + high) / 2;
		MSort(SR, TR2, low, mid);
		MSort(SR, TR2, mid + 1, high);
		Merge(TR2, TR1, low, mid, high);
	}
}
void Merge(int SR[], int TR[], int low, int mid, int high) {//第二个参数是目标
	int i = low, j = mid + 1, k = low;
	while (i <= mid && j <= high) {
		if (SR[i] < SR[j]) TR[k++] = SR[i++];
		else TR[k++] = SR[j++];
	}//一个指针到头,循环结束,剩下的放进来
	while (i <= mid) TR[k++] = SR[i++];
	while (j <= high) TR[k++] = SR[j++];

}
//非递归归并
void MergePass(int SR[], int TR[], int low, int high) {//第二个参数是目标
	int i = 1;
	int j;
	while (i <= high - 2 * low + 1) {//一二序列、三四序列..
		Merge(SR, TR, i, i + low - 1, i + 2 * low - 1);
		i = i + 2 * low;
	}
	if (i < high - low + 1) Merge(SR, TR, i, i + low - 1,high);
	else
		for (j = i; j <= high; j++)
			TR[j] = SR[j];
}
void MergeSort2(SqList *L) {//从最小序列开始
	int* TR = (int*)malloc(L->length * sizeof(int));/* 申请额外空间 */
	int k = 1;
	while (k < L->length) {
		MergePass(L->r, TR, k, L->length);//Lr归并n个子序列到TR
		k = 2 * k;/* 子序列长度加倍 */
		MergePass(TR, L->r, k, L->length);//TR归并更少但更长的序列回到LR
		k = 2 * k;/* 子序列长度加倍 */
	}
}
#pragma endregion






void print(SqList L) {
	int i;
	for (i = 1; i < L.length; i++)
		printf("%d,", L.r[i]);
	printf("%d", L.r[i]);
	printf("\n");
}
#define N 9
int main() {
	int d[N] = { 50,10,90,30,70,40,80,60,20 };
	SqList test;
	for (int i = 0; i < N; i++)
		test.r[i + 1] = d[i];
	test.length = N;
	printf("排序前:\n");
	print(test);
	printf("排序:\n");
	MergeSort2(&test);
	print(test);
	getchar();
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值