排序算法

(1)直接插入排序

    基本思想:将第一个序列看成已经有序的自序列,从第二个序列起依次进行插入,使得整个序列集体有序。

    时间复杂度为O(n^2),空间复杂度为O(1),稳定。

    特点:越有序越快,在所有元素全部有序的情况下时间复杂度为O(n)。

    代码如下:

void InsertSort(int *arr,int len)
{
	int i;
	int j;
	int tmp;
	for(i=1;i<len;i++)
	{
		tmp = arr[i];
		for(j=i-1;j>=0;j--)
		{
			if(arr[j] > tmp)
				arr[j+1] = arr[j];
			else
				break;
		}
		arr[j+1] = tmp;
	}
}
void test(int []arr,int len)
{
    if (arr == null)
        return;
    for(int i=1;i<len;++i)
    {
        int temp = arr[i];
        int j = I;

        while(arr[j-1]>temp)
        {
           arr[j] = arr[j - 1];
           j--;
        }
        arr[j] = temp;
    }
}

(2)希尔排序

    基本思想是:将整个待排序列分为若干子序列,分别进行直接插入排序,待整个待排序列基本有序时,再对所有序列进行一次直接插入排序。 

   时间复杂度为O(N^1.3)--O(N^1.5)之间,空间复杂度为O(1),不稳定。

    代码如下:

static void Shell(int *arr,int len,int gap)//gap是分几组,步长
{
	int i;
	int j;
	int tmp;
	for(i=gap;i<len;i++)
	{
		tmp = arr[i];
		for(j=i-gap;j>=0;j-=gap)
		{
			if(arr[j] > tmp)
				arr[j+gap] = arr[j];
			else
				break;
		}
		arr[j+gap] = tmp;
	}
}
void ShellSort(int *arr,int len)
{
	int d[] = {5,3,1};
	for(int i=0;i<sizeof(d)/sizeof(d[0]);i++)
	{
		Shell(arr,len,d[i]);
	}
}

(3)冒泡排序

    基本思想:经过一趟比较将最大的数(最小的数)放在最后一个,依次进行多趟比较,每一次确定一个.(相邻的两个待排序列

比较)。  

  时间复杂度是O(n^2),空间复杂度是O(1),稳定

    优化:当所有数据都有序时,它的时间复杂度仍然是O(n^2),那么可以增加一个状态量表示有没有数据交换,如果有则继

续,无则说明数据已经全部有序了。

    代码如下:

void BubbleSort(int *arr,int len)
{
	int tmp;
	for(int i=1;i<len;i++)
	{
		for(int j=0;j<len-i;j++)
		{
			if(arr[j] > arr[j+1])
			{
				tmp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = tmp;
			}
		}
	}
}

(4)快速排序

    基本思想:通过一次排序将待排记录分割成独立的两部分,其中一部分的所有关键字都小于另一部分的关键字,再依次对这两部分记录继续进行排序,以达整个序列有序。

    特点:当数据有序时退化为选择排序,时间复杂度为O(n^2).越有序越慢。

    时间复杂度是O(nlogN),空间复杂度是O(logN),不稳定。

    代码如下:

static int Partition(int *arr,int low,int high)
{
	int tmp = arr[low];
	while(low < high)
	{
		while((low<high) && (arr[high]>=tmp))
			high--;
		if(low < high)
			arr[low] = arr[high];
		else
			break;
		while((low<high) && (arr[low]<=tmp))
			low++;
		if(low < high)
			arr[high] = arr[low];
		else
			break;
	}
	arr[low] = tmp;
	return low;
}
void QuickSort1(int *arr,int len)
{
	int par = Partition(arr,0,len-1);
	int low = 0;
	int high = len-1;
	if(low+1<par)
		QuickSort1(arr,par-low);
	if(par+1<high)
		QuickSort1(arr+par+1,high-par);
}

(5)选择排序

    基本思想:从待排序的元素序列中选择关键字最小或最大的元素,将其放在已排序元素序列的最前面或最后面,其余的元素构成新的待排序元素序列,并从待排序元素序列中选择关键字最小的元素,将其放在待排序元素序列的最前面或最后面。

  时间复杂度是O(n^2),空间复杂度是O(1),不稳定

    优化:锦标排序

    代码如下:

void SelectSort(int *arr,int len)//选择排序
{
	int index;//存放每次找的最小值的下标
	int tmp;
	for(int i=0;i<len;i++)
	{
		index = i;//每次以I为基准,从i+1开始找
		for(int j=i+1;j<len;j++)
		{
			if(arr[j] < arr[index])
				index = j;
		}
		if(index != i)
		{
			tmp = arr[i];
			arr[i] = arr[index];
			arr[index] = tmp;
		}
	}
}

(6)堆排序

    建立大根堆的时间复杂度是O(nlogN),堆排序的时间复杂度是O(nlogN),空间复杂度是O(1),不稳定。

    代码如下:

void HeapAdjust(int *arr,int start,int end)
{
	int tmp = arr[start];
	int parent = start;

	for(int i=2*parent+1;i<=end;i=2*i+1)
	{
		if((i+1<=end) && (arr[i]<arr[i+1]))
		{
			++i;
		}//i一定是左右孩子较大值的下标

		if(tmp < arr[i])
		{
			arr[parent] = arr[i];
			parent = i;
		}
		else
			break;
	}
	arr[parent] = tmp;
}

void HeapSort(int *arr,int len)//O(nlogn),O(1),不稳定
{
	int i;
	int tmp;
	for(i=(len-1-1)/2;i>=0;i--)//O(nlogn)
	{
		HeapAdjust(arr,i,len-1);
	}

	for(i=0;i<len-1;i++)//O(nlogn)
	{
		tmp = arr[0];
		arr[0] = arr[len-1-i];
		arr[len-1-i] = tmp;

		HeapAdjust(arr,0,len-i-1-1);
	}
}

(7)归并排序

基本思想是:将两个或两个以上的元素有序序列组合,使其成为一个有序序列。

时间复杂度是O(nlogN),空间复杂度是O(n),不稳定。

代码如下:

static void Merge(int *arr,int len,int gap)//O(n)
{
	int low1 = 0;
	int high1 = low1+gap-1;
	int low2 = high1+1;
	int high2 = low2+gap<len ? low2+gap-1 : len-1;
	int *brr = (int *)malloc(len*sizeof(int));
	assert(brr != NULL);
	int i = 0;
	//归并段成对,需要归并
	while(low2 < len)
	{//两个归并段都还有数据
                while(low1<=high1 && low2<=high2)
		{
			if(arr[low1] <= arr[low2])
				brr[i++] = arr[low1++];
			else
				brr[i++] = arr[low2++];
		}
		//一个归并段已完成,另一个还有数据
		while(low1 <= high1)
			brr[i++] = arr[low1++];

		while(low2 <= high2)
		{
			brr[i++] = arr[low2++];
		}

		low1 = high2+1;
		high1 = low1+gap-1;
		low2 = high1+1;
		high2 = low2+gap<len ? low2+gap-1 : len-1;
	}

	//归并段不成对
	while(low1 < len)
		brr[i++] = arr[low1++];
	for(i=0;i<len;i++)
		arr[i] = brr[i];
	free(brr);
}

void MergeSort(int *arr,int len)//O(nlogn),O(n),稳定
{
	for(int i=1;i<len;i*=2)
		Merge(arr,len,i);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值