排序算法--逐步进阶

排序算法

冒泡排序

冒泡排序是比较排序算法中较为基础的一种,以下是原始算法以及其优化

经典冒泡

//冒泡排序原始算法
void bubbleSort(int a[],int n)
{
    int swapcout=0;
    int handlecount=0;
    for(int i=0;i<n;++i)//确定排序趟数
        {
            for(int j=0;j<n-i-1;++j)//确定比较次数,注意j的边界条件
            {
                if(a[j]>a[j+1])
                {
                    int temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                    swapcout++;
                }
            }
            handlecount++;
        }
         cout<<swapcount<<' '<<handlecount<<endl;

}

优化之减少排序趟数

/优化冒泡排序第一版
//加入flag,避免数组已经有序热然继续循环
void bubbleSort2(int a[],int n)
{
    int swapcout=0;
    int handlecount=0;

    for(int i=0;i<n;++i)
    {
        bool flag =true;
        for(int j=0;j<n-i-1;++j)
        {
            if(a[j]>a[j+1])
            {
                int tmp=a[j];
                a[j]=a[j+1];
                a[j+1]=tmp;
                flag=false;
                swapcout++;
            }
        }
        //如果flag为true,则数组已经有序
        if(flag)
        {
             cout<<swapcount<<' '<<handlecount<<endl;
            return;
        }
        handlecount++;
    }
}

优化之减少比较次数

//记录最后一次的交换位置,避免重复交换
void bubbleSort3(int a[],int n)
{
    int swapcount=0;
    int handlecount=0;
    int k=n-1;
    for(int i=0;i<n-1;++i)
    {
        bool flag =true;
        int loc = 0;//记录最后一次交换的位置
       for(int j=0;j<k;++j)
       {
           if(a[j]>a[j+1])
           {
               int tmp=a[j];
               a[j]=a[j+1];
               a[j+1]=tmp;
               loc=j+1;
               flag=false;
               swapcount++;
           }

       }
       k=loc;
       if(flag)
       {
           cout<<swapcount<<' '<<handlecount<<endl;
           return;
       }
       handlecount++;
    }
}

优化之双向冒泡(作用不大)

双向冒泡的思路是从前往后找最大值的时候,同时从后往前找最小值,达到并行的效果。
事实上,因为他们操作的是同一个数组,后一次的排序结果依赖于前一次排序的结果,所以无法做到真正的并行,优化效果不大。

void BubbleSort(int arr[], int len)
{
	int i = 0;
	int j = 0;
	int n = 0;//同时找最大值的最小需要两个下标遍历
	int flag = 0;
	int pos = 0;//用来记录最后一次交换的位置
	int k = len - 1;
	for (i = 0; i < len - 1; i++)//确定排序趟数
	{
		pos = 0;
		flag = 0;
		//正向寻找最大值
		for (j = n; j < k; j++)//确定比较次数
		{
			if (arr[j]>arr[j + 1])
			{
				//交换
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 1;//加入标记
				pos = j;//交换元素,记录最后一次交换的位置
			}
		}
		if (flag == 0)//如果没有交换过元素,则已经有序,直接结束
		{
			return;
		}
		k = pos;//下一次比较到记录位置即可
		//反向寻找最小值
		for (j = k; j > n; j--)
		{
			int tmp = arr[j];
			arr[j] = arr[j - 1];
			arr[j - 1] = tmp;
			flag = 1;
		}
		n++;
		if (flag == 0)//如果没有交换过元素,则已经有序,直接结束
		{
			return;
		}
	}
}

插入排序

选择排序

快速排序

较为经典的一种排序方式。思路也较为简单确立基准元素之后,让比基准元素小的和大的分别在基准元素的两端,再用分治的思想,对基准元素两端的数进行排序。

经典版本

void quicksort(int a[],int low,int high)
{
    //递归出口
    if(low>=high){
        return;
    }
    int i=low;
    int j=high;
    while(i<j)
    {
        while(i<j&&a[j]>=a[low])
        {
            j--;
        }
        while(i<j&&a[i]<=a[low])
        {
            i++;
        }
        //两数交换
        if(i<j)
        {
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    //i,j相等时与枢轴元素交换
    int temp2=a[low];
    a[low]=a[i];
    a[i]=temp2;
    //递归
    quicksort(a,low,i-1);
    quicksort(a,j+1,high);
}

改良版本

快排在原序列有序时时间复杂度会退化,所以要加入随机化。

归并排序

堆排序

桶排序

希尔排序

基数排序

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值