1. 程式人生 > >連通性問題--Algorithms IN C讀書筆記

連通性問題--Algorithms IN C讀書筆記

基礎 英文版 efi sni 數組元素 否則 每次 -m 添加

近期在看《Algorithms IN C》這本書。剛開始看,讀的是英文版的。感覺作者的敘述有點不太easy理解。就找了一本中文版的來看,發現還是看英文版的比較好。先看了第一章的大部分,後面的總結還沒有看,我的感受是。一個小的問題僅僅須要找到一個正確的算法就能夠了。根本不許要去考慮算法的效率和性能,僅僅有在解決一些大型的實際問題時,算法的優劣才幹體現出來。另外,就是添加機器的性能遠不如改善算法的性能貢獻大。

第一章舉了一個連通性的樣例,作者一步一步的引導我們來改進算法,使得這個算法終於能夠真正的用在實際問題中。這個問題的描寫敘述及四個解決算法,例如以下:

問題描寫敘述
   輸入兩個整數,代表兩個節點。假設這兩個整數沒有建立連接(這包含直接連接和通過其它節點連接),那麽我們就建立這兩個節點之間的連接。否則,繼續輸入下一個節點

四個逐步改進的算法例如以下:
//算法一
#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;
}

算法四就是在算法三的基礎之上又做了進一步的改進,將樹的深度進一步的縮小。

關於第二章算法分析的部分,準備留到以後再看,如今看了沒什麽深得體會。下一部分。準備開始看數據結構。

連通性問題--Algorithms IN C讀書筆記