0
点赞
收藏
分享

微信扫一扫

深度学习基础——循环神经网络的结构及参数更新方式


目录

快速排序-非递归

归并排序-非递归

八大排序分析


快速排序-非递归

void QuickSortNonR(int* a, int begin, int end)//栈实现
{
	Stack st;
	StackInit(&st);
	StackPush(&st, end);
	StackPush(&st, begin);
	while(!StackEmpty(&st))
	{
		int left = StackTop(&st);
		StackPop(&st);
		int right = StackTop(&st);
		StackPop(&st);
		int key = left;
		int i = left, j = right;

		//此处用i j快排一趟 key随关键值下标改变而改变
        while(i < j)
	    {
    		while(i < j && a[j] >= a[key]) j--;
		    while(i< j&& a[i] <= a[key]) i++;
		    Swap(a[i], a[j]);
	    }
    	Swap(a[i], a[key]);
	    key = i;//修正key

		if(left < key - 1)//子区间入栈 可以下面的if交换顺序 不重要 
        //只要Push的时候的两个区间左右下标都对应前面的left right即可。
		{
			StackPush(&st, key - 1);
			StackPush(&st, left);
		}
		if(key + 1 < right)
		{
			StackPush(&st, right);
			StackPush(&st, key + 1);
		}
	}
	StackDestroy(&st);
}

归并排序-非递归

oid MergeSortNonR(int* a, int n)
{
	int gap = 1;
	int* tmp = (int*)malloc(sizeof(int) * n);
	while(gap < n)
	{
		for(int i = 0; i < n; i += 2*gap)
		{
			//分为[i, i + gap - 1] [i+gap, i + 2*gap - 1]
			int l1 = i, r1 = i+gap-1;
			int l2 = i+gap, r2 = i+2*gap-1;
			int k = l1;
			//越界修正边界
			if(r1 >= n)
			{
				r1 = n - 1;
				l2 = n;
				r2 = n - 1;
			}
			else if(l2 >= n)
			{
				l2 = n;
				r2 = n - 1;
			}
			else if(r2 >= n)
				r2 = n - 1;
			while(l1 <= r1 && l2 <= r2)
			{
				if(a[l1] < a[l2]) 
				{
					tmp[k++] = a[l1];
					l1++;
				}
				else
				{
					tmp[k++] = a[l2];
					l2++;
				}
			}
			while(l1 <= r1) tmp[k++] = a[l1++];
			while(l2 <= r2) tmp[k++] = a[l2++];
		}
		memcpy(a, tmp, n * sizeof(int));
		gap *= 2;
	}
	free(tmp);
}

八大排序分析

时间复杂度:时间复杂度简单来说就是对一个算法所用的时间量级的表示,比如一个算法,你输入n个数据,他要大概循环n次,执行n次关键语句,那它的时间复杂度就是O(n)。

空间复杂度:空间复杂度是算法需要的额外空间的表示,比如归并n个数据,他需要开一个大小为n的临时数组,因此空间复杂度就是O(n)。

稳定性:排序算法的稳定性简单来说就是对于两个相等的数据,排序前后他们的相对顺序不变。
比如 1 3 1 2 排序后 1 1 2 3。红包依然在橙色前面。

排序算法时间复杂度空间复杂度稳定性分析
插入排序O(N)~O(N^2)O(1)稳定对于有序序列插入排序的时间最短,接近O(N),对于完全倒序的序列时间复杂度为O(N^2)。因为是一个一个数据往前比较插入,所以相同数据不会交换,是稳定的。
希尔排序平均O(N^1.3)O(1)不稳定只需要记住平均复杂度就行,详细分析比较复杂,可以去查其他资料。因为是按照步长插排的,所以不一定稳定。
选择排序O(N^2)O(1)不稳定每次选择最大最小为n次循环,要选择n次,所以一共是n*n=n^2的时间复杂度,因为选择完后直接是按位置交换,而不考虑交换的时候谁大谁小,所以不稳定。 
堆排序O(NlogN)O(1)不稳定原序列建堆调整为logn,遍历为n,所以时间复杂度为nlogn。
冒泡排序O(N)~O(N^2)O(1)稳定相邻比较交换,所以稳定。优化之后,对于有序序列,遍历一次发现没有交换就会break,所以最好是O(N),最坏O(N^2)。
快速排序O(NlogN)~O(N^2)O(logN)不稳定递归需要开辟函数栈帧,非递归也需要栈或队列模拟,所以空间复杂度是logN。对于完全有序的序列来说快排时间复杂度会降低到N^2,此时可以使用取mid为key来优化。
归并排序O(NlogN)O(N)稳定归并需要有临时数组,所以空间复杂度O(N)。因为是两个序列比较,按大小顺序加入到临时数组中,所以是稳定的。

举报

相关推荐

0 条评论