算法导论1

最近在看《算法导论》,身为初学者想做些笔记来记录自己的学习过程,大神请飘过大笑自己将书中的伪代码用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);
	}
	
}

















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值