各种排序算法(冒泡,插入,选择,快速,堆,归并) 待续。。

各种排序算法实现及比较

1. 冒泡排序,时间复杂度O(N^2),“冒泡”:每次将最大的数放到数组末尾

两层循环,外层为趟数,内层实现每趟将最大的数移到数组尾部。每一趟针对未排序的数组,从头开始每次比较相邻的两个数,如果后面的数比前面的数小,就交换这两个数,一趟比较完之后最大的数就交换移到了数组最尾部。

void BubbleSort(vector<int> array)
{
    int len=array.size();
    for(int i=0;i<len;i++)
    {
        for(int j=1;j<len-i;j++)
        {
            if(array[j]<array[j-1])
                {
                    int temp=array[j];
                    array[j]=array[j-1];
                    array[j-1]=temp;
                }
        }
    }
}

2. 插入排序,时间复杂度O(N^2),“插入”:每次将数插入排序数组中合适的位置

两层循环,外层循环的i将数组分为两部分,左边是排好序的,右边是没有排序的,内层循环j指向没排序的第一个数字,先存下这个数字temp,然后将这个数字依次与前面的数字(从j-1开始到0)比较,如果当前数字比temp大,就将其后移一位,直到不满足这个条件,退出循环,将当前位置填上temp。

void InsertSort(vector<int> array)
{
    int len=array.size();
    for(int i=0;i<len;i++)
    {
        int j=i;
        int temp=array[j];
        while(j>0)
        {
            if(temp<array[j-1])
            {
                array[j]=array[j-1];
                j--;
            }
            else
                break;
        }
        array[j]=temp;
    }
}

3. 选择排序,时间复杂度O(N^2),“选择”:每次遍历未排序数组选择最小的数与第一个数交换

两层循环,外层循环的i将数组分为两部分,左边是排好序的,右边是没有排序的,内层循环j指向没排序的第一个数字。每次遍历右边没有排序的数组,找到最小的数字,与第一个位置(j)的数字交换。

void SelectSort(vector<int> array)
{
    int len=array.size();
    for(int i=0;i<len-1;i++)
    {
        int k=i;
        for(int j=i+1;j<len;j++)
        {
            if(array[j]<array[k])
                {
                    k=j;
                }
        }
        if(k!=i)
        {
            int temp=array[i];
            array[i]=array[k];
            array[k]=temp;
        }
    }
}

4. 快速排序,时间复杂度O(NlogN)

分两步,首先在数组中选择一个基准数字,然后遍历数组,使得比基准数小的数都移到左边,比基准数大的都移到右边,然后对左右两边的数组进行快速排序,通过递归完成。

函数partition实现的功能:将基准数小的数都移到左边,比基准数大的都移到右边,并且返回基准值位置。

void QuickSort(vector<int> array, int low, int high)
{
	if(low>=high)
		return;
	int pos=partition(array, low, high);
	if(pos>low)
	{
		QuickSort(array, low, pos-1);
	}
	if(pos<high)
	{
		QuickSort(array, pos+1, high);
	}
}

重点是partition函数,用两个前后指针完成两两交换,当i=j时停止循环,将最左边数字设为基准值,i从pos+1先往后走一直遇到第一个大于base的,j往前走一直遇到第一个小于base的,交换i和j位置的值,。最后结束循环的时候,交换小于基准值数组的最右边位置的值和基准值位置的值,要注意i指向的有可能是小于基准值数组的最右边的值(array[i]<base),也可能是大于基准值数组最左边的值(array[i]>base),如果是第二种情况,则应该交换i-1位置的。

int partition(vector<int> &array, int low, int high)
{
	int pos=low;
	int base=array[pos];
	int i=low+1;
	int j=high;
    while(i<j)
    {
        while(i<j&&array[i]<=base)
        {
            i++;
        }
        while(i<j&&array[j]>=base)
        {
            j--;
        }
		swap(array[i],array[j]);
    }
	int p;
	if(array[i]>base)
		p=i-1;
	else
		p=i;

	swap(array[p],array[pos]);
	return p;
}

猜你喜欢

转载自blog.csdn.net/u012991043/article/details/81090164
今日推荐