排序

关于排序

排序是计算机的一项基本应用。许多最终通过计算机生成的输出是以某种方式排序输出的,并且内部调用排序过程使得许多计算变得很有效率。因此在计算机科学中,排序也许是研究最多且最重要的一种运算。

接下来讨论 整数组元素 排序的问题。

插入排序(C++)

// 小-->大
void InSort(int *a, int length)
{
	int j,temp;
	for (int i = 1; i < length; i++)//数组下标从1(第二个元素)开始,temp作监视哨,第一个数据(a[0])无可比性
	{
		j = i - 1;                   //确定要比较元素的最右边
		temp = a[i];                 //给监视哨赋值
		while ((j >= 0) && (temp < a[j]))
		{
			a[j + 1] = a[j];         //数据右移
			j--;                     //移向左边一个没比较的数
		}
		a[j+1] = temp;             //确定的位置插入a[i]
	}
}
//测试
//int a[] = {25, 12, 36, 45, 2, 9, 39, 22, 98, 37 };
//InSort(a, 10);

Shell排序(C++)

/**
待排序记录按照下标增量分组,对每一组使用直接插入排序,
随着增量逐渐减少,魅族记录会越来越多,当增量减为1时,算法终止
**/
void ShellSort(int *a, int length)
{
	//增量逐渐减少 n/2,n/4,n/8.....
	int delta = length / 2;              //求得数组下角标增量
	int i,j,temp;
	while (delta >= 1)                   //增量 >=1
	{
		for (j = delta; j < length; j++) //从增量处开始分组(0,Δ),(1,Δ+1)...
		{
			i = j - delta;               
			temp = a[j];
			while ((i >= 0) && (temp < a[i]))
			{
				a[i + delta] = a[i];     //增量分组中实现插入排序
				i = i - delta;
			}
			a[i + delta] = temp;
		}
		delta = delta / 2;               //更换增量大小
	}
}
//测试
//int a[] = {25, 12, 36, 45, 2, 9, 39, 22, 98, 37 };
//ShellSort(a, 10);

交换排序(C++)

//冒泡排序
/**
不断交换反序对,直到不再出现反序对为止
**/
void swap(int &a, int &b)                //交换数值函数,传递引用
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
void BubbleSort(int *a, int length)
{
	for (int i = length; i >= 1;i--)     //一次冒泡出现最大数,第二此出现次大数......              
	{
		for (int j = 0; j < i-1; j++)    //内部循环从零开始,两两交换
		{
			if (a[j]>a[j+1])
			{
				//int temp;
				//temp = a[j];
				//a[j] = a[j+1];
				//a[j+1] = temp;         //等价于交换函数
				swap(a[j], a[j + 1]);    //交换函数
			}
		}
	}
}

//冒泡排序改进算法
void BubbleSortA(int *a, int length)
{
	int bound = length-1;                 //终止位置初始化
	while (bound != 0)
	{
		int tempbound = 0;                //记录一趟冒泡排序,最后交换记录的位置
		for (int j = 0; j < bound; j++)   //数组(0.....n-1) 最后为a[n-1],记录住最后一次交换的位置 bound
		{
			if (a[j] > a[j + 1])            
			{
				int temp;
				temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp; 
				tempbound = j;
			}
		}
		bound = tempbound;                //更新边界
	}
}
//测试
//int a[] = {25, 12, 36, 45, 2, 9, 39, 22, 98, 37 };
//ShellSortA(a, 10);

快速排序(C++)

//快速排序
/**
选取文件中中一个记录作为基准元素,然后按照关键词的大小进行排序,使得基准元素左边都小于它,右边都大于它
**/
int partition(int arr[], int left, int right)  //找基准数划分,注:left,right 是数组中实实在在的下角标
{
	int i = left;
	int j = right + 1;     //最右边增1
	int temp = arr[left];
	while (i < j)
	{
		while (arr[i] <= temp)
		{
			i++;
		}
		j = j - 1;
		while (arr[j] > temp)
		{
			j--;
		}
		if (i < j)
			swap(arr[i], arr[j]);
	}
	swap(arr[j], arr[left]);  //注意:此时交换时,不要使用temp
	return j;
}
void quick_sort1(int arr[], int left, int right)
{
	if (left > right)
		return;
	int j = partition(arr, left, right);
	quick_sort1(arr, left, j - 1);
	quick_sort1(arr, j + 1, right);
}
//快速排序-填坑法
void quick_sort(int s[], int l, int r)
{
	if (l < r)
	{
		int i = l, j = r, x = s[l];
		while (i < j)
		{
			while (i < j && s[j] >= x) // 从右向左找第一个小于x的数
				j--;
			if (i < j)
				s[i++] = s[j];

			while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数
				i++;
			if (i < j)
				s[j--] = s[i];
		}
		s[i] = x;
		quick_sort(s, l, i - 1); // 递归调用 
		quick_sort(s, i + 1, r);
	}
}
//测试
//int a[] = {277, 12, 36, 45, 2, 19, 39, 22, 98, 37 };
//quick_sort1(a, 0, 9);
//quick_sort(a, 0, 9);

选择排序(C++)

//6.选择排序
//直接选择排序-对文件进行n-1次选择,第i次操作是,选择第i小或大的记录放在第i个位置上
//选择排序
//直接选择排序-对文件进行n-1次选择,第i次操作是,选择第i小或大的记录放在第i个位置上
void SSort(int *a, int length)
{
	for (int j = length-1; j >= 1; j--)// j 为每次比较后大值要放置的位置的下角标
	{
		int t = 0;                     //每次用第一项 来比较
		for (int i = 1; i <= j; i++)// 获取最大值的下角标 赋值 t
		{
			if (a[t] < a[i])
			{
				t = i;
			}
		}
		swap(a[j], a[t]);
	}
}
void SelectSort(int *a, int length)
{
	for (int i = 0; i < length - 1; i++)// i为每次循环比较后要放置的小值的下角标
	{
		int k = i;
		for (int j = i + 1; j < length; j++)
		{
			if (a[j] < a[k])//获取小值的下角标
			{
				k = j;
			}
		}//确定最小值下角标
		if (k != i)
		{
			swap(a[k], a[i]);
		}
	}
}
//测试
//int a[] = {27, 12, 36, 45, 2, 19, 39, 22, 98, 37 };
//SSort(a,10);

堆排序

void HeapAdjust( int S[], int i, int nlength)
{
    int nChild;
    int nTemp;
    for (; 2 * i + 1 < nlength; i = nChild)
    {
        nChild = 2 * i + 1;
        //得到子节点中较大的节点
        if (nChild < nlength - 1 && S[nChild + 1] > S[nChild])
            nChild++;
        //如果较大的子节点大于父节点那么把较大的子节点往上移动,替换它的父节点
        if (S[i] < S[nChild])
        {
            nTemp = S[i];
            S[i] = S[nChild];
            S[nChild] = nTemp;
        }
        else
            break;
    }
}
void Heapsort(int A[], int length)
{
    int i;//调整序列的前半部分元素,调整完之后第一个元素是序列的最大元素
    int temp;
    for (i = length / 2 - 1; i >= 0; i--)
        HeapAdjust(A, i, length);
    //从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
    for (i = length - 1; i >= 0; i--)
    {
        //把第一个元素和当前的最后一个元素交换
        //保证当前的最后一个位置的元素都是现在这个序列中最大的
        temp = A[0];
        A[0] = A[i];
        A[i] = temp;
        //不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
        HeapAdjust(A, 0, i);
    }
}
//测试
//int a[] = {27, 12, 36, 45, 2, 19, 39, 22, 98, 37 };
//Heapsort(a,10);
//for(int i = 0;i<10;i++)
//      cout<<a[i]<<" ";

排序算法的评价

1.操作时间:关键字的比较和数据元素的移动所需时间。
2.空间:执行算法所需要的辅助存储空间的大小。
3.排序算法的稳定性:简单形式化定义为:如果A[i] = A[j],排序前A[i]在A[j]之前,排序后A[i]还在A[j]之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。
4.排序算法稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位排序后元素的顺序在高位也相同时是不会改变的。

在这里插入图片描述

陆续更新中…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值