排序算法汇总与代码实现(c++)

参考文章:https://www.cnblogs.com/zhaoshuai1215/p/3448154.html

(实在写的太好了!)

排序算法共有九种:

插入排序,折半排序,希尔排序,冒泡排序,快速排序,简单选择排序,堆排序,归并排序,基数排序。

总叙述:

常见的排序算法都是比较排序,非比较排序包括计数排序、桶排序和基数排序,非比较排序对数据有要求,因为数据本身包含了定位特征,所有才能不通过比较来确定元素的位置。

排序的稳定性和复杂度

      不稳定:

      选择排序(selection sort)— O(n2)

      快速排序(quicksort)— O(nlogn) 平均时间, O(n2) 最坏情况; 对于大的、乱序串列一般认为是最快的已知排序

      堆排序 (heapsort)— O(nlogn)

      希尔排序 (shell sort)— O(nlogn)

      基数排序(radix sort)— O(n·k); 需要 O(n) 额外存储空间 (K为特征个数)

 

      稳定:

      插入排序(insertion sort)— O(n2)

      冒泡排序(bubble sort) — O(n2)

      归并排序 (merge sort)— O(n log n); 需要 O(n) 额外存储空间

      二叉树排序(Binary tree sort) — O(nlogn); 需要 O(n) 额外存储空间

      计数排序  (counting sort) — O(n+k); 需要 O(n+k) 额外存储空间,k为序列中Max-Min+1

      桶排序 (bucket sort)— O(n); 需要 O(k) 额外存储空间

总结一下:

o(nlogn)的排序算法有4种,快速排序,堆排序,归并排序,希尔排序。

排序算法的稳定性是指:排序过后,元素的相对位置不会发生变化。

满足o(nlogn),同时还稳定的算法是归并排序。但需要o(n)的开销。

稳定的算法包括归并排序,冒泡排序,计数排序,二叉树排序,桶排序,插入排序(。。怎么可能记得住。。)

非比较排序包括:计数排序,桶排序,基数排序

1.插入排序

2.冒泡排序

#。。。为什么粘贴下来的排版乱起八糟。。

#include<iostream>
using namespace std;
#define LENGTH 6


class sort
{
	int number[LENGTH];
public:
	sort()
	{
		cout<<"i am first!"<<endl;
		cout<<"please input six numbers!"<<endl;
		for(int i=0;i<LENGTH;i++)
			cin>>number[i];
	}
	void bubble();
	void printNumber()
	{
	    cout<<"---------------"<<endl;
	    for(int i=0;i<LENGTH;i++)
        {
            cout<<number[i]<<" ";
        }
	}
//	void exchange();//瞬间感觉我又得回去看指针和引用了
};

void sort::bubble()
{
//冒泡排序基本思想:
//有两层循环:每一次执行一个循环,
//循环里目前位置与下一个位置进行比较,如果前一个比后一个大,就交换位置
//内循环停止的条件是,当目前位置到了N-1处
//外循环是进行n-1次循环,直到后一个位置到了第二个
    int t;//保存中间值
    int flag = 0;
    for(int end = LENGTH;end >= 1;end--)//这是外层循环
    {
        for(int i=0;i<end-1;i++)//内层循环
        {
            if(number[i]>number[i+1])//内层的执行的判断条件
            {
                t = number[i];
                number[i] = number[i+1];
                number[i+1] = t;
                flag = 1;
            }
        }
        if(flag == 0)
            break;//如果一趟没有交换过,就证明顺序是对的,退出冒泡排序。
    }
    printNumber();
}


int main()
{
	sort s;
	s.bubble();
}

3.快速排序

#include <bits/stdc++.h>

using namespace std;

/*
快速排序的基本思想是:
1.先选定一个基准
2.从右往左看,遇到比它小的,就停下
3.从左往右看,遇到比它大的,也停下
4.每次选取第一个值为基准,然后i和j调换位置,一轮排序完成

5.结束的条件是什么?
用递归实现
记住:递归实现的几个条件:
(1)满足什么条件可以继续下去
(2)继续下去的操作
(3)一切由参数决定,就是传进来的参数必须是可变的。。//越讲越糊涂了
*/
class quickSort
{
public:
    void print_a(int *a,int len)
    {
        cout<<"this is print_a!"<<endl;
        int i=0;
        while(i<=len)
        {
            cout<<*(a+i)<<" ";
            i++;
        }
    }
    int sort(int *a,int i,int j)
    {
//        令第一个数字做基准,i是要排序的a的首部,j是要排序的a的尾部,i,j是原数组的位置
//      结束的条件
        cout<<"i:"<<i<<",j:"<<j<<endl;
        if(i<j)
        {
            int endnum = j;
            int startnum = i;
            int t = i;
            i = i+1;
            while(i<j)
            {
                while(*(a+j)>*(a+t))
                {
                    int flag = 1;
                    if(j>i)
                    {
                        j--;
                        flag = 0;
                    }
                    if(flag)
                        break;
                }
//            最终j会停在比基准大的地方,或者i=j的地方
                while(*(a+i)<*(a+t))
                {
                    int flag = 1;
                    if(i<j)
                    {
                        i++;
                        flag = 0;
                    }
                    if(flag)
                        break;
                }
                if(i<j)
                {
                    int k;
                    k = *(a+i);
                    *(a+i) = *(a+j);
                    *(a+j) = k;
                }

            }
            if(i==j)
            {
                int k;
                k = *(a+t);
                *(a+t) = *(a+i);
                *(a+i) = k;
            }
            print_a(a,endnum-startnum);
            sort(a,startnum,i-1);
            sort(a,i+1,endnum);
        }:
        print_a(a,9);
    }
};

4.堆排序

#include <bits/stdc++.h>

using namespace std;

class heapSort
{
public:
    /*
    调整大顶堆的思路是:
    1.设置一个flag,一旦一个过程中没有任何调整,则大顶堆调整结束
    2.每次开始调整的元素是len/2-1
    3.每次调整的元素(即父节点i与子节点的关系是2i+1,2i+2)
    */

    void print_a(int *a,int len)
    {
        cout<<"this is print_a!"<<endl;
        int i=0;
        while(i<=len)
        {
            cout<<*(a+i)<<" ";
            i++;
        }
    }
//    这个函数是用来判断是不是大顶堆的
    bool isHeap(int *a,int len)
    {
        int i = len/2-1;
        int left,right;
        while(i>=0)
        {
            left = 2*i+1;
            right = 2*i+2;
            if(right<len)
            {
                if((*(a+i)>=*(a+left)) && (*(a+i)>=*(a+right)))
                    i--;
                else
                {
                    cout<<"not big heap!continue!"<<endl;
                    return 0;
                }
            }else{
                if(*(a+i)>=*(a+left))
                    i--;
                else{
                    cout<<"not big heap!continue!"<<endl;
                    return 0;
                }
            }
        }
        cout<<"this is the big heap!!!"<<endl;
        return 1;
    }
    void adjustHeap(int *a,int len)
    {
        int i = len/2-1;
        int flag = 1;//有没有调整过的标志,调整过flag = 1;
        int left,right;
//        如果还不是大顶堆,就一直调整
        while(!isHeap(a,len))
        {
            i = len/2-1;
            while(i>=0)
            {
                left = 2*i+1;
                right = 2*i+2;
                //若有右子树
                if(right<len)
                {
                    if(*(a+i)>=*(a+left) && *(a+i)>=*(a+right))
                        i--;
                    else
                    {
                        if(*(a+left)>*(a+right))
                        {
                            int t = *(a+left);
                            *(a+left) = *(a+i);
                            *(a+i) = t;
                        }
                        else
                        {
                            int t = *(a+right);
                            *(a+right) = *(a+i);
                            *(a+i) = t;
                        }
                        i--;
                    }
                }else
                {
                    if(*(a+i)>=*(a+left))
                        i--;
                    else{
                        int t = *(a+i);
                        *(a+i) = *(a+left);
                        *(a+left) = t;
                    }
                }
            }
            print_a(a,9);
        }
    }
    void sort(int *a,int len)
    {
        print_a(a,len-1);
        int t;
        while(len>=1)
        {
            adjustHeap(a,len);
            t = a[0];
            a[0] = a[len-1];
            a[len-1] = t;
            len--;
        }
        print_a(a,9);
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值