最近在看《算法导论》,身为初学者想做些笔记来记录自己的学习过程,大神请飘过自己将书中的伪代码用C实现并贴了出来,由于是初学者所以说对书中的内容理解的也许还不够充分,代码有的地方也不够简洁和合理,欢迎大家指正(代码均在vc++6.0中测试无误)。
书中首先介绍了一些排序算法。
1,插入排序(Insertion-sort)
时间复杂度Θ(n²)
由于比较简单直接贴上自己的代码
#include<stdio.h>
int main ()
{
int a[10]={3,2,1,4,6,7,9,0,5,4};
int i ,j,key;
for(j=1;j<10;j++)//移动j向数组的右方前进
{
key=a[j];
i=j-1;
while(i>=0 && a[i]<key)//移动i向已排序的左方移动
{
a[i+1]=a[i];
i--;
}
a[i+1]=key;
}
for(int b=0;b<10;b++)
{
printf("%d ",a[b]);//打印已完成排序的数组
}
return 0;
}
2.归并排序(Merge-sort)
时间复杂度Θ(nlgn)
归并排序运用了分治法的思想。
分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解。
分治法的三个步骤:分解(Divide),解决(Conquer),合并(Combine)。
代码为(含哨兵):
#include<stdio.h>
#include<stdlib.h>
void Merge(int * num,int p,int q,int r);
void Mergesort(int * num,int p,int r);
int main()
{
int num[13]={12,34,2,4,6,8,9,90,66,11,78,45,98};
Mergesort(num,0,12);
for(int i=0;i<13;i++)
{
printf("%3d",num[i]);
}
printf("\n");
return 0;
}
void Merge(int * num,int p,int q,int r)
{
int n1,n2;
int i,j=0,k;
n1=q-p+1;
n2=r-q;
int * L=(int *)(malloc(sizeof(int)*n1));//左数组
int * R=(int *)(malloc(sizeof(int)*n2));//右数组
for(i=0;i<n1;i++)
{
*(L+i)=*(num+p+i);
}
*(L+n1)=10000;//设置哨兵元素,防止越界
for(i=0;i<n1;i++)
{
*(R+i)=*(num+q+i+1);
}
*(R+n2)=10000;//设置哨兵
i=0;
for(k=p;k<=r;k++)
{
if(L[i]<=R[j])
{
num[k]=L[i];
i++;
}
else
{
num[k]=R[j];
j++;
}
}
}
void Mergesort(int *num,int p,int r)
{
int q;
if(p<r)
{
q=(p+r)/2;
Mergesort(num,p,q);
Mergesort(num,q+1,r);
Merge(num,p,q,r);
}
}
归并排序与二叉树的后序遍历类似,下面两幅图会便于理解归并排序的实现思路。
数组A[9-16]包含元素{2,4,5,7,1,2,3,6},将其分为L[]和R[]数组,最后一个元素为哨兵元素。A中浅阴影位置包含他们的最终值,L和R中的浅阴影位置包含有待于被复制回A的值。
课后练习题的无哨兵元素实现,代码如下:
#include <stdio.h>
#include <stdlib.h>
void Merge(int *num,int p,int q,int r);
void Mergesort(int *num,int p,int r);
int main ()
{
int num[13]={12,34,2,4,6,8,9,90,66,11,78,45,98};
Mergesort(num,0,12);
for(int i=0;i<13;i++)
{
printf("%3d",num[i]);
}
printf("\n");
return 0;
}
void Merge(int *num,int p,int q,int r)
{
int n1,n2;
int i,j,k;
n1=q-p+1;
n2=r-q;
int *L = (int *)(malloc(sizeof(int)*n1));
int *R = (int *)(malloc(sizeof(int)*n2));
for(i=0;i<n1;i++)
{
*(L+i)=*(num+p+i);
}
for(i=0;i<n2;i++)
{
*(R+i) = *(num+q+1+i);
}
i=0,j=0,k=p;
while(i<n1 && j<n2)
{
if(L[i]<R[j])
{
num[k]=L[i];
i++;
}
else
{
num[k]=R[j];
j++;
}
k++;
}
while(i<n1) //左数组是否越界
{
num[k]=L[i];
i++;
k++;
}
while(j<n2)//右数组是否越界
{
num[k]=R[j];
j++;
k++;
}
}
void Mergesort(int *num,int p,int r)
{
int q;
if(p<r)
{
q=(p+r)/2;
Mergesort(num,p,q);
Mergesort(num,q+1,r);
Merge(num,p,q,r);
}
}