常用五大排序算法总结

注:以下算法代码为编程过程中自己排序根据基本性能和要求所创造的一个备忘录,经常写着代码忘记了排序算法怎么写,如有侵权,请联系我删除

1.插入排序

算法步骤 :

        1.从第一个元素开始,通常认为该元素已经排序,从第二个元素开始
        2.取下一个元素elem,从已排序的元素序列从后往前扫描
        3.如果该元素大于elem,则将该元素移到下一位
        4.重复步骤3,直到找到已排序元素中小于等于elem的元素
        5.elem插入到该元素的后面,如果已排序所有元素都大于elem,则将elem插入到下标为0的位         置,首位
        6.重复步骤2~5

思路:通常认为是N-1个序列有序,加入第N个序列,也使这个序列成为有序序列。但是通常不检验该序列是否有序,插入位置,应从头开始比较。即为首位元素有序。依次加入剩余元素。由于算法思想,当该序列有序,即为从小到大升序,时间复杂度也为o(n),最好情况,这里采用的是直接插入方法。

代码实现:

void insertsort(elemtype a[],int length)//elemtype 是数据类型,length为数组长度
{
    for (int i = 1; i < length; i++)
    {
        elemtype temp = a[i];     //从第二为数据开始插入排序
        int j = i;
        while (j > 0 && a[j - 1] > temp)//设置j>0,当前一位元素大于后一位时,交换元素
        {
            a[j] = a[j - 1];
            j--;
        }
        a[j] = temp;
    }
}
//双层循环,平均时间复杂度O(n*n),最坏时间时间复杂度也为O(n*n),空间复杂度O(1)

补充:算法稳定性稳定

2.冒泡排序

被认为是所有算法中最为简单的一个初学者算法,但是由于其时间复杂度和性能低,而被大部分程序不喜欢

冒泡排序算法的原理如下: 

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 

  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 

  3. 针对所有的元素重复以上的步骤,除了最后一个。 

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

   代码实现:

void bubbleSort(elemtype a[], int length)
{
	int begin = length;
	while (begin)
	{
		int flag = 0;
		for (int i = 1; i < end; ++i)
		{
			if (a[i - 1] > arr[i])
			{
				elemtype tem = arr[i];
				a[i] = a[i - 1];
				a[i - 1] = tem;
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;
		}
		--begin;
	}
}

3.选择排序

算法思想

  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
  2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  3. 重复第二步,直到所有元素均排序完毕。其中最小的元素是除之前已经找到的元素中,最小的
//选择排序
void selectionsort(elemtype num[], int length)
{
    for (int i = 0; i < length - 1; i ++)
    {
        int j = i;
        for (int k = i + 1; k < length; k++)
        {
            if (num[k] < num[j])
            {
                j = k;
            }
        }
 
        if (j != i)
        {
            elemtype temp = num[j];
            num[j] = num[i];
            num[i] = temp;
        }
    }
}

4.归并排序

1.概念

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的

步骤:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

  4. 重复步骤3直到某一指针达到序列尾

  5. 将另一序列剩下的所有元素直接复制到合并序列尾

代码实现:

//first和end为num第一个元素和最后一个元素的索引
void merge_sort(int num[], int first, int end)
{
    if (first < end)
    {
        int mid = (first + end) / 2;
        merge_sort(num, first, mid);
        merge_sort(num, mid + 1, end);
        merge(num, first, mid, end);
    }
}
 
//合并序列[start, mid]、[mid+1, end]
void merge(int num[], int first, int mid, int end)
{
    int n1 = mid - first + 1;
    int n2 = end - mid;
    int* L = new int[n1];
    int* R = new int[n2];
    for(int i = 0; i < n1; i++)
    {
        L[i] = num[first + i];
    }
 
    for (int j = 0; j < n2; j++)
    {
        R[j] = num[mid + j + 1];
    }
 
    int i = 0;
    int j = 0;
    int k = first;
    while(i < n1 && j < n2)
    {
        if (L[i] < R[j])
        {
            num[k++] = L[i++];
        }
        else
        {
            num[k++] = R[j++];
        }
    }
 
    while (i < n1)
    {
        num[k++] = L[i++];
    }
 
    while (j < n2)
    {
        num[k++] = R[j++];
    }
 
    delete [] L;
    delete [] R;
}

5.快速排序

概念:快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

代码实现:

void quick_sort(int num[], int left, int right)
{
    if (left < right)
    {
        int i = left;
        int j = right;
        int x = num[i];
        while (i < j)
        {
            while (i < j && num[j] >= x)
            {
                j--;
            }
            if(i < j)
            {
                num[i++] = num[j];
            }
 
            while (i < j && num[i] < x)
            {
                i++;
            }
            if(i < j)
            {
                num[j--] = num[i];
            }
        }
        num[i] = x;
 
        quick_sort(num, left, i - 1);
        quick_sort(num, i + 1, right);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪心算法(Greedy Algorithm)是一在每一步选择中都采取当前状态下最优的选择,从而希望最终导致全局最优的算法。贪心算法通常有以下特点: 1. 贪心选择性质:每一步都采取最优的选择,即局部最优解。 2. 最优子结构性质:原问题的最优解包含子问题的最优解。 3. 无后效性:每一步的决策只与当前状态有关,与之前的决策无关。 贪心算法可以用来求解一些最优化问题,如最小生成树、背包问题、活动选择问题等。 以活动选择问题为例,假设有n个活动,每个活动有一个开始时间s和结束时间f,多个活动可能在同一时间段内进行,但是同一时间只能进行一个活动。如何选择活动,使得能够安排的活动数量最多? 贪心算法的思路是:按照结束时间从早到晚排序,每次选择结束时间最早的活动,且不与已经选择的活动时间冲突。这是因为选择结束时间最早的活动,可以给后面留下更多的时间选择其他活动,从而使得总的安排活动数量最多。 参考代码如下: ``` #include <iostream> #include <algorithm> using namespace std; struct Activity { int start, finish; }; bool compare(Activity s1, Activity s2) { return (s1.finish < s2.finish); } void printMaxActivities(Activity arr[], int n) { sort(arr, arr+n, compare); cout << "Selected activities:\n"; int i = 0; cout << "(" << arr[i].start << ", " << arr[i].finish << "), "; for (int j = 1; j < n; j++) { if (arr[j].start >= arr[i].finish) { cout << "(" << arr[j].start << ", " << arr[j].finish << "), "; i = j; } } } int main() { Activity arr[] = {{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}}; int n = sizeof(arr)/sizeof(arr[0]); printMaxActivities(arr, n); return 0; } ``` 输出结果为: ``` Selected activities: (1, 2), (3, 4), (5, 7), (8, 9), ``` 可以看到,按照贪心算法的思路,选择了4个活动,使得能够安排的活动数量最多。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值