连通性问题--Algorithms IN C读书笔记

     最近在看《Algorithms IN C》这本书,刚开始看,读的是英文版的,感觉作者的叙述有点不太容易理解,就找了一本中文版的来看,发现还是看英文版的比较好。先看了第一章的大部分,后面的总结还没有看,我的感受是,一个小的问题只需要找到一个正确的算法就可以了,根本不许要去考虑算法的效率和性能,只有在解决一些大型的实际问题时,算法的优劣才能体现出来。另外,就是增加机器的性能远不如改善算法的性能贡献大。

     第一章举了一个连通性的例子,作者一步一步的引导我们来改进算法,使得这个算法最终可以真正的用在实际问题中。这个问题的描述及四个解决算法,如下:

问题描述
   输入两个整数,代表两个节点,如果这两个整数没有建立连接(这包括直接连接和通过其他节点连接),那么我们就建立这两个节点之间的连接,否则,继续输入下一个节点

四个逐步改进的算法如下:
//算法一
#include <stdio.h>

#define N 10

int main(void)
{
    int id[N];
    int t,i,p,q;

    //一定要初始化啊
    for(i=0;i<N;i++)
    {
        id[i] = i;
    }

    while( scanf("%d%d",&p,&q)==2 )
    {
        if( id[p]==id[q] )
            continue;
        t = id[p];
        for(i=0;i<N;i++)
        {
            if( id[i]==t )
            {
                id[i] = id[q];
            }
        }

        for(i=0;i<N;i++)
        {
            printf("%d\t",id[i]);
        }
        printf("\n");
    }

    return 0;
}

     这四个算法所使用的数据结构都是数组,算法一是把连接(包括直接连接和间接连接)在一起的整数所对应的数组元素都赋值为相同的值。


//算法二
#include <stdio.h>

#define N 10

int main(void)
{
    int id[N];
    int i,j,p,q;

    for(i=0;i<N;i++)
    {
        id[i] = i;
    }

    while( scanf("%d%d",&p,&q)==2 )
    {
        //必须使用下面两次循环,否则当心陷入死循环
        for(i=p;id[i]!=i;i=id[i]);
        for(j=q;id[j]!=j;j=id[j]);

        if( i==j )
            continue;
        id[i] = j;

        for(i=0;i<N;i++)
        {
            printf("%d\t",id[i]);
        }
        printf("\n");
    }

    return 0;
}

     算法二采用的数据结构仍然是数组,但是逻辑上确实树的结构。我们首先根据输入的两个整数,分别找到其所在的树的根节点,然后检测两个节点所在的树的根节点是否相同,如果相同,就说明是同一棵树,否则就把这两个根节点连接起来。


//算法三
#include <stdio.h>

#define N 10

int main(void)
{
	int id[N],sz[N];
	int p,q,i,j;

	for(i=0;i<N;i++)
	{
		id[i] = i;
		sz[i] = 1;
	}	

	while( scanf("%d%d",&p,&q)==2 )
	{
		for(i=p;id[i]!=i;i=id[i]);
		for(j=q;id[j]!=j;j=id[j]);
		if( sz[i]<sz[j] )
		{
			id[i] = j;
			sz[j] += sz[i];
		}
		else
		{
			id[j] = i;
			sz[i] += sz[j];
		}
		
		printf("i=%d\nj=%d\n",i,j);

		for(i=0;i<N;i++)
		{
			printf("%d\t",sz[i]);
		}
		printf("\n");
		
		for(i=0;i<N;i++)
		{
			printf("%d\t",id[i]);
		}
		printf("\n");
	}

	return 0;
}   

     算法三是在算法二的基础之上改进而来的,但是它添加了一个数据结构,记录以每个节点为根的树中的元素的个数。通过这个数据结构,每次都把小树连接到大树上,防止树的深度过深。


//算法四
#include <stdio.h>

#define N 10

int main(void)
{
	int id[N];
	int sz[N];
	int p,q,i,j;

	//初始化
	for(i=0;i<N;i++)
	{
		id[i] = i;
		sz[i] = 1;
	}

	while( scanf("%d%d",&p,&q)==2 )
	{
		for(i=p;id[i]!=i;i=id[i])
		{
			id[i] = id[id[i]];
		}
		for(j=q;id[j]!=j;j=id[j])
		{
			id[j] = id[id[j]];
		}

		if( sz[i]<sz[j] )
		{
			id[i] = j;
			sz[j] += sz[i];
		} 
		else
		{
			id[j] = i;
			sz[i] += sz[j];
		}

        printf("i=%d\nj=%d\n",i,j);

        for(i=0;i<N;i++)
        {
            printf("%d\t",sz[i]);
        }
        printf("\n");

        for(i=0;i<N;i++)
        {
            printf("%d\t",id[i]);
        }
        printf("\n");
	}

	return 0;
}

     算法四就是在算法三的基础之上又做了进一步的改进,将树的深度进一步的缩小。

     关于第二章算法分析的部分,准备留到以后再看,现在看了没什么深得体会,下一部分,准备开始看数据结构。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《算法:C语言实现(第1-4部分)基础知识、数据结构、排序及搜索(原书第3版)》细腻讲解计算机算法的C语言实现。全书分为四部分,共16章。包括基本算法分析原理,基本数据结构、抽象数据结构、递归和树等数据结构知识,选择排序、插入排序、冒泡排序、希尔排序、快速排序方法、归并和归并排序方法、优先队列与堆排序方法、基数排序方法以及特殊用途的排序方法,并比较了各种排序方法的性能特征,在进一步讲解符号表、树等抽象数据类型的基础上,重点讨论散列方法、基数搜索以及外部搜索方法。书中提供了用C语言描述的完整算法源程序,并且配有丰富的插图和练习,还包含大量简洁的实现将理论和实践成功地相结合,这些实现均可用在真实应用上。 《算法:C语言实现(第5部分)图算法(原书第3版)》是深入论述算法的三卷本教程《算法:C语言实现》(第3版)中的第二卷——图算法。作者在这次修订中重写了许多内容,增加了数千个新练习、数百个新图表、数十个新程序,并对图表和程序做了详尽的注释说明。新版中不仅涵盖了新的主题,而且还提供了对许多经典算法的更充分的解释,包括图的性质、图搜索、有向图、最小生成树、最短路径和网。《算法:C语言实现(第5部分)图算法(原书第3版)》涵盖了足够的基本内容及较详细的图算法高级主题,既可单独用作数据结构与算法课程的教材,也可与第一卷(第1~4部分)结合使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值