排序算法(一)

一、基本概念:

1.排序算法是一种很重要的算法,许多其他算法是以排序算法为基础的。排序算法主要有冒泡排序、插入排序、希尔排序、选择排序、堆排序、归并排序、快速排序。

2.内部排序:在内存空间里完成数据的排序,一次完成

3.排序的稳定性:如果两个大小相等的元素在排序后相对位置不变,则排序是稳定的

4.没有一种排序在任意情况下都是最好的,需要分情况使用

二、算法实现:

1.冒泡排序:大泡泡不断往上

(1)优化:设置一个tag,如果某一次排列都没有执行,则退出循环

(2)适用于链表

(3)只交换严格满足大于的元素,算法稳定

(4)时间复杂度:O(N2)

(5)算法实现(C++):

void Bubble_sort(int a[], int n)
{
	for (int i =n-1; i !=0; i--)
	{
		for (int j = 0; j != i; j++)    //把最大的元素放到最后
		{
			if (a[j + 1] < a[j])    //只有严格小于才交换元素,算法是稳定的
			{
				int t = a[j];
				a[j] = a[j + 1];
				a[j + 1] = t;
			}
		}
	}
}

(6)算法优化:

void BBubble_sort(int a[], int n)
{
	int flag = 0;    //设置一个flag用于表示是否发生了交换
	for (int i = n - 1; i != 0; i--)
	{
		flag = 0;
		for (int j = 0; j != i; j++)    //一次冒泡
		{
			if (a[j + 1] < a[j])    
			{
				flag = 1;    //标识发生了交换
				int t = a[j];
				a[j] = a[j + 1];
				a[j + 1] = t;
			}
		}
		if (flag == 0)    //如果有任何一次没有发生交换,则退出循环
			break;
	}
}

2.插入排序:类似于打扑克牌抓牌

(1)每次抓一张牌,与前一张牌比较,比前一张小的话则把前一张牌向后移动,否则插入

(2)在序列基本有序的情况下,插入排序简单高效

(3)时间复杂度:O(N2)

(4)算法实现(C++):

void Insertion_sort(int a[], int n)
{
	int i = 0;
	for (int p = 1; p != n; p++)
	{
		int temp = a[p];    //摸下一张牌
		for (i = p; i >= 1 && a[i-1] > temp; --i)
			a[i] = a[i - 1];    //移出空位
		a[i] = temp;    //插入新牌
	}
}

3.希尔排序:对插入排序的优化,预先使序列有序一点

(1)设置一个增量序列,对每个增量序列进行插入排序

(2)时间复杂度:选取不同的增量序列时间复杂度不同,通常为O(N1.5)

(3)算法实现(增量序列N/2):

void Shell_sort(int a[], int n)
{
	for (int D = n / 2; D != 0; D /= 2)    //增量序列
	{
		int i = 0, p = 0;
		for (p = D; p != n; p++)    //一次增量排序
		{
			int temp = a[p];
			for (i = p; i >= D && a[i - D] > temp; i -= D)    
				a[i] = a[i - D];
			a[i] = temp;
		}
	}
}

4.选择排序:每次从无序序列中选择最小的元素放入有序序列的末尾

(1)时间复杂度:O(N2)

(2)每执行一次,都把最小元素放到序列最前面

(3)算法实现:

void Selection_sort(int a[], int n)
{
	for (int i = 0; i != n-1; i++)    //n次排序,每次把最小的元素与最左边元素交换
	{
		int min = i;
		for (int j = i+1; j != n; j++)    //查找未排序部分的最小元素的下标
			if (a[j] < a[min])
				min = j;
		int t = a[i];    //交换元素
		a[i] = a[min];
		a[min] = t;
	}
}

三、举个栗子(leetcode973.最接近原点的k个点)

(1)首先采用插入排序算法,但是运行超过了时间限制

(2)考虑使用选择排序,只需进行K次即可

vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        Selection_sort(points,K);
	    vector<vector<int>> out;
	    for (int i = 0; i != K; i++)
		    out.push_back(points[i]);
	    return out;
    }
    void Selection_sort(vector<vector<int>>& v,int K)
    {
	    int min = 0;
	    int min_t = 0;
	    int p = 0;
	    for (int i = 0; i !=K; i++)
	    {
		    min = v[i][0] * v[i][0] +v[i][1] * v[i][1];
		    min_t = i ;
		    for (p = i+1 ; p != v.size(); p++)
		    {
			    int temp = v[p][0] * v[p][0] + v[p][1] * v[p][1];
			    if (temp < min)
			    {
				    min_t = p;
				    min = temp;
			    }
				
		    }
		    if (min_t != i)
		    {
			    vector<int> temp2 = v[i];
			    v[i] = v[min_t];
			    v[min_t] = temp2;
		    }
	    }

(3)可以用堆排序进行优化

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务