存储过程 Kruskal算法

kruskal算法

克鲁斯卡尔算法是求解最小生成树的一种算法,通过对图里的边排序,对这些边进行遍历,如果没有构成回路(关于回路是通过终点来判断的),那么添加进mst里。具体可以参考:http://www.cnblogs.com/skywang12345/p/3711500.html#anchor6 里面包含了C++版的实现

存储过程实现克鲁斯卡尔算法

  • 首先需要了解存储过程的含义、应用场景、如何创建、如何执行;
  • mac下使用navicat来写存储过程;
  • 了解存储过程的语法,包括输入输出参数、变量定义和赋值、逻辑判断、循环的执行以及退出循环等,跟接触任何一门新语言类似;
  • 开始会疑惑,怎么在sql中去表述这些数据结构,比如数组等,其实就是表格来存储数据,设计对应的结构,增删改查就对应着对数据结构的操作。

直接附上源码:

BEGIN 
-- declare something 
    DECLARE pointNumber int DEFAULT 0;
    DECLARE i int DEFAULT 1;
    DECLARE edgNumber int default 0;
    DECLARE v INT; 
    DECLARE p1 int DEFAULT 0;
    DECLARE p2 int default 0;
    DECLARE leastCost int default 0;
    declare m int DEFAULT 0;
    declare n int default 0;
    declare Temp int default 0;

-- create table:graph the origin data table
    drop table if EXISTS graph;
    create table graph (
        id int(4) not null PRIMARY key auto_increment,
        Source int(4) not null,
        Target int(4) not null,
        Cost int(4) not null
    );
-- test data
    INSERT INTO graph(Source,Target,Cost) VALUES(1,2,5),(2,1,5),(1,3,3),(3,1,3),(2,3,2),(3,2,2),(2,5,2),(5,2,2),(3,5,4),(5,3,4),(2,4,8),(4,2,8);
-- another test data    
-- INSERT INTO graph(Source,Target,Cost) VALUES(1,2,12),(2,1,12),(2,3,10),(3,2,10),(3,4,3),(4,3,3),(4,5,4),(5,4,4),(3,5,5),(5,3,5),(3,6,6),(6,3,6),(5,6,2),(6,5,2),(5,7,8),(7,5,8),(6,7,9),(7,6,9),(2,6,7),(6,2,7),(1,6,16),(6,1,16),(1,7,14),(7,1,14); 

-- create table PointEnd:we can find the end pind of some point. Through this,we can judge whther we add it in the mst
    DROP TABLE if EXISTS PointEnd;
    CREATE table PointEnd (
        id int(4) not null PRIMARY key auto_increment,
        Source int(4) not null,
        Target int(4) not null
    );  

-- create table Mst:store the min spanning tree
    drop table if EXISTS Mst;
    create table Mst (
        id int(4) not null PRIMARY key auto_increment,
        Source int(4) not null,
        Target int(4) not null,
        Cost int(4) not null
    );

-- init PointEnd table
    SELECT  COUNT(DISTINCT Source) into pointNumber from graph;
    WHILE i<=pointNumber DO
        insert into PointEnd(Source,Target) VALUES(i,i);
        SET i=i+1;
    END WHILE;


-- loop
    loop_label: LOOP
        -- get the least cost from table graph  
        SELECT MIN(Cost) into leastCost from graph;
        -- select leastCost;
        -- select Source,Target,Cost from graph where Cost=leastCost;
        -- get least cost's point
        select Source,Target,Cost into p1, p2,leastCost from graph where Cost=leastCost limit 1;
        -- delete the edge from graph
        DELETE from graph where Source=p1 AND Target=p2;
        DELETE from graph where Source=p2 AND Target=p1;
        -- select p1,p2,cost;
        -- get start point and target point's end point
        select Target into m from PointEnd where Source=p1;
        select Target into n from PointEnd where Source=p2;

        if m!=n THEN
            insert into Mst(Source,Target,Cost) VALUES(p1,p2,leastCost);
            insert into Mst(Source,Target,Cost) VALUES(p2,p1,leastCost);

            if m>n THEN
                SELECT Target into Temp from PointEnd where Source=n;
                UPDATE PointEnd SET Target=m where Source=n;
                UPDATE PointEnd SET Target=m where Target=Temp;
            ELSE 
                SELECT Target into Temp from PointEnd where Source=m;
                UPDATE PointEnd SET Target=n where Source=m;
                UPDATE PointEnd SET Target=n where Target=Temp;         
            END IF;

        END IF;

-- exit the loop,when mst's edge is equal to the pointNumber-1
        select COUNT(Source) into edgNumber from Mst;
        if edgNumber=(pointNumber-1)*2 THEN 
        -- if edgNumber=2 THEN
            LEAVE loop_label;
        END IF;

    END LOOP loop_label;

END

总结

实现这个和另外一个游标的题目,花了一天的时间,学习了存储过程的写法,包括加注释、声明变量、通过select调试查看变量值、判断运算符是”=”号、有些问题可以重新连接数据库来解决,同时对写sql语句也熟悉了一些。

你可能感兴趣的:(存储过程,kruskal)