插入排序法示例:
将想要插入的值搜索找到合适的位置,之前的数值一一向后移动一个位置,腾出一个空位置给想要插入的数值。
伪代码:
Instert-Sort(A)
for j=2 to A.length
key = A[j]
i = j - 1
while i>0 and A[i] > key
A[i+1] = A[i]
i = i - 1
A[i+1] = key
几种比较常用的算法分析:
1、最坏情况分析:
T(n)定义为输入规模为n时的最长运行时间
2、平均情况分析:
此时T(n)就成了输入规模为n时,所有可能输入的期望时间,也即每种输入的运行时间乘以那种输入出现的概率(加权平均)
3、最好情况分析(一般不去关注)
那么插入排序的最坏情况时间是多少?
注意的一些问题:
1、计算机的性能
2、比较算法时,通常比较的是其相对速度,也即两个算法在同一台机器上的表现。
3、绝对速度?真有某种算法能无论在什么机器上运行都表现得更好吗?
算法分析的大局观:渐进分析
其思想为:忽略掉哪些依赖于机器的常量,以及不是去检查实际的运行时间而是去关注运行时间的增长T(n),n->无穷
渐进符号:
θ符号:弃去公式中低阶项,并忽略前面的常数因子
θ(n^3)算法与θ(n^2)算法相比,从数学角度上看,总有一个n使得θ(n^3)算法会比θ(n^2)算法开销还大,但是从工程角度上讲,这个n有可能连计算机也运算不到,因此就会有:尽管用渐进的观点来看,他们有可能很慢,但他们仍然可以在合理的规模输入下运行的更快,这也是为什么有时会关注一些较慢的算法!!!
对于插入排序的最坏情况:输入的序列已经逆序排列好了
T(n) = θ(n^2)
归并排序代码:
#include<stdio.h>
#include<stdlib.h>
#define ARRAY_NUM (10)
int merge(int *array, int min, int mid, int max)
{
int i=0, j=0, idx=0;
int lnum = mid-min+1, rnum = max-mid;
int *L=NULL, *R=NULL;
L = (int*)calloc(1, lnum*sizeof(int));
if(NULL == L)
{
return -1;
}
R = (int*)calloc(1, rnum*sizeof(int));
if(NULL == R)
{
return -1;
}
/* Set L and R array */
for(i=0; i<lnum; i++)
{
L[i] = array[min+i];
}
for(j=0; j<rnum; j++)
{
R[j] = array[mid+1+j];
}
/* Sort */
i = 0;
j = 0;
idx = min;
while(i<lnum && j<rnum)
{
if(L[i] <= R[j])
{
array[idx++] = L[i++];
}
else
{
array[idx++] = R[j++];
}
}
if(i < lnum)
{
for(; i<lnum; i++)
{
array[idx++] = L[i];
}
}
else
{
for(; j<rnum; j++)
{
array[idx++] = R[j];
}
}
free(L), L=NULL;
free(R), R=NULL;
return 0;
}
int merge_sort(int *array, int min, int max)
{
if(max > min) {
int mid = (min+max)/2;
merge_sort(array, min, mid);
merge_sort(array, mid+1, max);
merge(array, min, mid, max);
}
return 0;
}
int main(int argc, void *argv[])
{
int idx=0;
int array[ARRAY_NUM] = {0, 9, 8, 7, 6, 5, 4, 3, 2, 1};
merge_sort(array, 0, ARRAY_NUM-1);
for(idx=0; idx<ARRAY_NUM; idx++)
{
fprintf(stdout, "array[%d] = %d\n", idx, array[idx]);
}
system("pause");
return 0;
}
该程序中的merge_sort函数递归调用,将一个数组分解成一个个最小单元然后,通过merge合并函数将其合并排序恢复到元数组中。
举例:
归并操作的思想:
1.申请空间,使其大小为两个已经排序串行之和,该空间用来存放合并后的串行
2.设定两个指针,最初位置分别为两个已经排序串行的起始位置
3.比较两个指针所指的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4.重复步骤3直到某一指针到达串行的尾部
5.将另一串行剩下的元素直接复制到合并串的尾部
归并算法的T(n)=θ(nlgn)其中lg为以2为底的对数!!!!