算法 - 几种常见的排序算法(选择、插入、冒泡、希尔、快速、归并)

6 篇文章 0 订阅

几种常见的排序算法:选择排序、插入排序、冒泡排序、希尔排序、快速排序、归并排序。

1、选择排序

基本思想:每一趟(例如第i趟,i=0,1,...,n-2),在后面的n-i个待排的数据元素中选出关键字(最小的元素),作为有序元素序列的第i个元素。

排序过程:

排序算法:

void myswap(int a[], int& i, int& j)
{
	int tmp = a[i];
	a[i] = a[j];
	a[j] = tmp;
}

//选择排序
void SelectSort(int a[], int len)
{
	int i = 0;
	int j = 0;

	for (i = 0; i < len; i++)
	{
		for (j = i + 1; j < len; j++)
		{
			if (a[i] > a[j])
			{
				myswap(a, i, j);
			}
		}
	}
}

2、插入排序

基本思想:v[0],v[1],...,v[i-1]已经排好序,这时,用v[i]的关键字与v[i-1],v[i-2]的关键字进行比较,找到插入的位置即将v[i]插入,原来位置上的对象向后顺移。

插入排序的关键点:1、拿出一个元素,留出位置;2、符合条件的元素后移

排序过程:

排序算法:

void InsertSort(int a[], int len)
{
	int i = 0;
	int j = 0;
	int k = 0;

	for (i = 1; i < len; i++)
	{
		k = i;	//待插入的位置
		int tmp = a[k];
		for (j = i - 1; (j >= 0)&&(tmp < a[j]); j--)
		{
			a[j + 1] = a[j];
			k = j;		//插入位置
		}
		a[k] = tmp;
	}
}

3、冒泡排序

排序过程:

主要是相邻接点进行比较。

排序算法:

void BubbleSort(int a[], int len)
{
	int i = 0;
	int j = 0;

	bool sort_tag = true;	//是否排好序的标志,true:未排好序,false:排好序
	for (int k = 0; k < len && sort_tag; k++)
	{
		sort_tag = false;		//每一趟默认排好序
		for (i = 0; i < len - 1; i++)
		{
			j = i + 1;
			if (a[i] > a[j])
			{
				myswap(a, i, j);
				sort_tag = true;		//只要发生了数据交换,就说明这一趟之前未排好序
			}//未发生任何交换,则说明已经排好序了,下一趟没必要执行了,sort_tag仍为false
		}
	}
}

4、希尔排序

基本思想:

1)、先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;

2)、然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止。

3)、算法复杂度O(nlogn);希尔排序是不稳定的。d0=len,d(i) = d(i-1)/3+1        //业界公认

排序过程:

排序算法:

void ShellSort(int a[], int len)
{
	int i = 0;
	int j = 0;
	int k = 0;
	int gap = len;

	do
	{
		gap = gap / 3 + 1;
		for (i = gap; i < len; i++)
		{
			k = i;	//待插入的位置
			int tmp = a[k];
			for (j = i - gap; (j >= 0) && (tmp < a[j]); j-=gap)
			{
				a[j + gap] = a[j];
				k = j;		//插入位置
			}
			a[k] = tmp;
		}
	} while (gap > 1);
}

 分组化的插入排序,常规插入排序的间隔是1,希尔排序中插入排序的间隔是gap,gap是变化的。

5、快速排序

基本思想:快速排序是对冒泡排序的一种改进。

1)、通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小,基准数据排在这两个子序列的中间;

2)、然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列;

3)、算法复杂度:O(nlogn);不稳定分组

递归地把数据分成两部分、partition

排序过程:

排序算法:

int partition(int a[], int low, int high)
{
	int tar = a[low];

	while (low < high)
	{
		//low上是tar
		while ((low < high) && (a[high] >= tar))
			high--;
		myswap(a, low, high);		//交换之后high上是tar		

		while ((low < high) && (a[low] <= tar))
			low++;
		myswap(a, low, high);		//再次交换后low上是tar
	}

	return low;
} 

void sort(int a[], int low, int high)
{
	if(low<high)
	{
		int mid_index = partition(a, low, high);

		sort(a, low, mid_index-1);		//左侧
		sort(a, mid_index + 1, high);		//右侧
	}
}

//快速排序
void QuickSort(int a[], int len)
{
	int low = 0;
	int high = len-1;
	
	sort(a, low, high);
}

6、归并排序

基本思想:将两个或两个以上的有序序列合并成一个新的有序序列;

排序过程:

 

排序算法:

void Merge(int src[], int des[], int low, int mid, int high)
{
	int i = low;
	int j = mid + 1;
	int k = low;

	while ((i <= mid) && (j <= high))
	{
		if (src[i] < src[j])
		{
			des[k++] = src[i++];
		}
		else
		{
			des[k++] = src[j++];
		}
	}

	while (i <= mid)		//若还剩几个尾部元素
	{
		des[k++] = src[i++];
	}

	while (j <= high)		//若还剩几个尾部元素
	{
		des[k++] = src[j++];
	}
}

void mSort(int src[], int des[], int low, int high, int max)
{
	if (low == high)	//只有一个元素时,不需要归并,结果直接赋给des[low]
	{
		des[low] = src[low];
	}
	else   //如果有多个元素,则进行两路归并
	{
		int mid = (low + high) / 2;
		int* space = (int*)malloc(sizeof(int)*max);

		//递归进行两路,两路划分
		//当剩下一个元素时,递归划分结束,然后开始merge归并操作
		if (nullptr != space)
		{
			mSort(src, space, low, mid, max);
			mSort(src, space, mid+1, high, max);
			Merge(space, des, low, mid, high);		//调用归并函数进行归并
		}

		free(space);
	}
}

void MergeSort(int a[], int len)
{
	mSort(a, a, 0, len-1, len);
}

7、排序方法比较

 

关于具体的排序算法实现细节可以参考:https://download.csdn.net/download/bailang_zhizun/12670773

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值