数据结构------内部排序法

总结一些算法的实现:

交换排序*****

1.冒泡算法

typedef struct arr1
{
	int data;
	int key; //关键字项必须能比较大小
}arr1;
void  BubbleSort(arr1 goal[], int n)
{
	int i;
	int j;
	arr1 tmp;
	bool flag;
	for (i = 0; i < n - 1; ++i)//每次循环确定一个最小数排在最前面,每次得出的有序区都是全局有序
	{
		flag = false;
		for (j = n - 1; j > i; --j)	//遍历一次元素数为n的数组,22对比,得出最小的排在前面
		{
			if (goal[j].key < goal[j - 1].key) //这要用j-1,因为j+1超过数组下标了。
			{
				tmp = goal[j];
				goal[j] = goal[j - 1];
				goal[j - 1] = tmp;
				flag = true;			//		有交换时证明没有排序完
			}
		}
		if (!flag)		//	m没有交换时证明排玩了,跳出循环结束排序。
			return;
	}
}

2.快速排序

//时间复杂度为O(nlog2n),空间复杂度为O(log2n);

void QuickSort(arr1 goal[], int s, int t)
{
	int i, j;
	arr1 tmp;
	//s t是数组的开始和结束
	i = s;
	j = t;

	if (s < t)
	{
		tmp = goal[i]; //第一个中心,中心用哪个都得
		while (i != j)
		{
			while (j > i && goal[j].key >= tmp.key) //把小于中心标志的数抛到左边
			{
				--j;
			}
			goal[i] = goal[j];
			while (i < j && goal[i].key < tmp.key) //把大于中心标志的数抛到右边
			{
				++i;
			}
			goal[j] = goal[i];
		}
		goal[i] = tmp;  // 当i = j时跳出循环,这时i和前面的某个值是一样的,
                      //把他换为tmp的中心标志,这样一轮的替换完成,左边小于tmp,右边大于tmp
		QuickSort(goal, s, i - 1);		//对左区间递归
		QuickSort(goal, i + 1, t);		//对右区间递归
	}
}

插入排序*****

3.直接插入

//该算法的时间复杂度最坏的情况是倒序时的O(n2),最好是正序时的O(n);其平均复杂度是O(n2)
void InsertSort1(arr1 goal[], int n)
{
	int i;
	int j;
	arr1 tmp;
	for (i = 1; i < n; ++i)
	{
		tmp = goal[i]; //第一轮是arr【1】,因为用第一项来做最开始的对比,之后就慢慢插入
		j = i - 1;      //新的有序区范围
		while (j >= 0 && tmp.key < goal[j].key) // 遍历查找tmp的插入下标
		{
			goal[j + 1] = goal[j];   //因为要插入元素,后面的元素要往后挪动
			j--;
		}
		goal[j + 1] = tmp;    //向有序区插入
	}
}

4.希尔排序

//直接排序法的一种,时间复杂度一般认为是O(n1.3),一般是最后一趟出有序区,他是不稳定的排序(还没有想向出他的插入图)
void InsertSort3(arr1 goal[], int n)
{
	int i;
	int j;
	int gap;
	arr1 tmp;
	gap = n/2;                   //初始增量
	while (gap > 0)
	{
		//确定增量之后用直接插入法
		for (i = gap; i < n; ++i)
		{
			tmp = goal[i]; //第一轮是arr【1】,因为用第一项来做最开始的对比,之后就慢慢插入
			j = i - gap;
			while (j >= 0 && tmp.key < goal[j].key) // 遍历查找tmp的插入下标
			{
				goal[j + gap] = goal[j];
				j = j - gap;         //j是一个增量一个增量的减少(可以说吧希尔的增量变为1就是直接插入)
			}
			goal[j + gap] = tmp;    //向有序区插入
		}
		gap = gap / 2;				//减小增量
	}
}

选择排序*****

5.直接选择

//和冒泡差不多,就是把排序放到外循环,使得可以定一个需要的有序区。
void SelectSort(arr1 goal[], int n)
{
	int i, j, k;
	arr1 tmp;
	for (i = 0; i < n; ++i) //在这里定一个需要的有序区,例如在10000个数理找最小的前10个数,就是把n设为10;
	{
		k = i;
		for (j = i + 1; j < n - 1; ++j)
		{
			if (goal[j].key < goal[k].key)
			{
				k = j; //确定最小值的下标
			}
		}
		if (k != i)	//排序
		{
			tmp = goal[i];
			goal[i] = goal[k];
			goal[k] = tmp;
		}
	}
}

6.归并排序

//2路归并排序
void Merge(arr1 goal[], int low, int mid, int hight)
{
	arr1 *R1;
	int i = low, j = mid + 1, k = 0; //k是R1的下标, i,j分别是1,2段的下标
	R1 = new arr1[hight - low + 1]();
	while (i <= mid && j <= hight)
	{
		if (goal[i].key <= goal[j].key)			//将第一段复制到R1
		{
			R1[k] = goal[i];
			++i, ++k;
		}
		else									//将第二段复制到R1
		{
			R1[k] = goal[j];
			++j, ++k;
		}
	}
	while (i <= mid)							//将第一段余下部分复制到R1
	{
		R1[k] = goal[i];
		++i, ++k;
	}
	while (j <= hight)							//将第二段余下部分复制到R1
	{
		R1[k] = goal[j];
		++j, ++k;
	}

	for (k = 0, i = low; i <= hight; k++, i++) //将R1复制会goal中
	{
		goal[i] = R1[k];
	}
	delete[] R1;
}

void MergePass(arr1 goal[], int lenght, int n)				//对整个表进行归并
{
	int i;
	for (i = 0; i + 2 * lenght - 1 < n; i = i + 2 * lenght)	//归并lenght长度的2个表
	{
		Merge(goal, i, i + lenght - 1, i + lenght * 2 - 1);	//
	}
	if (i + lenght - 1 < n)									//余下这2个表的长度,后者小于lenght,归并这2个表
	{
		Merge(goal, i, i + lenght - 1, n - 1);
	}
}
//二路归并排序
void MergeSort(arr1 goal[], int n)
{
	int lenght;
	for (lenght = 1; lenght < n; lenght = 2 * lenght)
	{
		MergePass(goal, lenght, n);
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值