您的位置:首页 > 数据库

pl/sql 实现归并算法 (合并插入法的优化)

2014-11-18 00:25 393 查看
CREATE OR REPLACE PACKAGE PG_MERGESORT IS

-- Author  : wealth_khb@126.com
-- Created : 2009-10-20 10:09:16
-- Purpose :

TYPE EMP_SSN_ARRAY IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; ---声明数组类型
BEST_EMPLOYEES EMP_SSN_ARRAY; ----数组

BIG_UPPER    INTEGER;
MIDDLE_VALUE NUMBER; ---------最大
-- Public function and procedure declarations
------初始化过程
PROCEDURE PRO_MERGESORT(UPPER_N IN NUMBER);
FUNCTION FUN_MERGESORT(UPPER_ARRAY IN EMP_SSN_ARRAY) RETURN EMP_SSN_ARRAY;
FUNCTION FUN_MERGE(LEFT_ARRAY  IN EMP_SSN_ARRAY,
RIGHT_ARRAY IN EMP_SSN_ARRAY) RETURN EMP_SSN_ARRAY;
END PG_MERGESORT;
(包体部分)

CREATE OR REPLACE PACKAGE BODY PG_MERGESORT IS

PROCEDURE PRO_MERGESORT(UPPER_N IN NUMBER) IS
V_EMP_SSN_ARRAY EMP_SSN_ARRAY;
V_L             INTEGER;
BEGIN
V_L       := 1;
BIG_UPPER := UPPER_N; ---最大长度
------对数组赋值
FOR X IN 1 .. BIG_UPPER LOOP
BEST_EMPLOYEES(X) := X * (DBMS_RANDOM.VALUE(X, 1));
END LOOP;
---返回
DBMS_OUTPUT.PUT_LINE('排序前'||V_EMP_SSN_ARRAY.COUNT||'个');
FOR P IN BEST_EMPLOYEES.FIRST .. BEST_EMPLOYEES.LAST LOOP
DBMS_OUTPUT.PUT_LINE(BEST_EMPLOYEES(P));
END LOOP;
V_EMP_SSN_ARRAY := FUN_MERGESORT(BEST_EMPLOYEES);
---递归调用返回结果左边
DBMS_OUTPUT.PUT_LINE('结果输出'||V_EMP_SSN_ARRAY.COUNT||'个');
FOR v_1 IN V_EMP_SSN_ARRAY.FIRST .. V_EMP_SSN_ARRAY.LAST LOOP
DBMS_OUTPUT.PUT_LINE(V_EMP_SSN_ARRAY(v_1));
END LOOP;

END;
-----------------------------------------------------
FUNCTION FUN_MERGESORT(UPPER_ARRAY IN EMP_SSN_ARRAY) RETURN EMP_SSN_ARRAY IS
V_UPPER     NUMBER(18, 0);
V_MIDDLE    NUMBER(18, 0);
V_VALUE     EMP_SSN_ARRAY;
LEFT_ARRAY  EMP_SSN_ARRAY; ----数组
RIGHT_ARRAY EMP_SSN_ARRAY; ----数组

BEGIN

--------

V_UPPER := UPPER_ARRAY.COUNT;
IF (UPPER_ARRAY.COUNT = 1 OR UPPER_ARRAY.COUNT = 0) THEN
RETURN UPPER_ARRAY;
END IF;

V_MIDDLE := floor(UPPER_ARRAY.COUNT / 2);

FOR X IN 1 .. V_MIDDLE LOOP
LEFT_ARRAY(X) := UPPER_ARRAY(X);
RIGHT_ARRAY(X) := UPPER_ARRAY(X + V_MIDDLE);
END LOOP;

IF (MOD(V_UPPER, 2) = 0) THEN
NULL;
ELSE
LEFT_ARRAY(V_MIDDLE + 1) := UPPER_ARRAY(V_UPPER);
END IF;

LEFT_ARRAY  := FUN_MERGESORT(LEFT_ARRAY);
RIGHT_ARRAY := FUN_MERGESORT(RIGHT_ARRAY);
----进行归并

V_VALUE := FUN_MERGE(LEFT_ARRAY, RIGHT_ARRAY);
RETURN V_VALUE;
END;

FUNCTION FUN_MERGE(LEFT_ARRAY  IN EMP_SSN_ARRAY,
RIGHT_ARRAY IN EMP_SSN_ARRAY) RETURN EMP_SSN_ARRAY IS
V_EMP_SSN_ARRAY EMP_SSN_ARRAY;
V_INT           INTEGER := 0;
V_LEFT          INTEGER := 0;
V_RIGHT         INTEGER := 0;
V_LEFT_ARRAY    EMP_SSN_ARRAY;
V_RIGHT_ARRAY   EMP_SSN_ARRAY;

BEGIN
V_LEFT_ARRAY  := LEFT_ARRAY;
V_RIGHT_ARRAY := RIGHT_ARRAY;

WHILE ((V_LEFT < V_LEFT_ARRAY.COUNT) AND
(V_RIGHT < V_RIGHT_ARRAY.COUNT)) LOOP
IF (V_LEFT_ARRAY(V_LEFT + 1) < V_RIGHT_ARRAY(V_RIGHT + 1)) THEN
V_INT := V_INT + 1;
V_LEFT := V_LEFT + 1;
V_EMP_SSN_ARRAY(V_INT) := V_LEFT_ARRAY(V_LEFT);
ELSE
V_INT := V_INT + 1;
V_RIGHT := V_RIGHT + 1;
V_EMP_SSN_ARRAY(V_INT) := V_RIGHT_ARRAY(V_RIGHT);
END IF;
END LOOP;

WHILE (V_LEFT < V_LEFT_ARRAY.COUNT) LOOP
V_INT := V_INT + 1;
V_LEFT := V_LEFT + 1;
V_EMP_SSN_ARRAY(V_INT) := V_LEFT_ARRAY(V_LEFT);
END LOOP;

WHILE (V_RIGHT < V_RIGHT_ARRAY.COUNT) LOOP
V_INT := V_INT + 1;
V_RIGHT := V_RIGHT + 1;
V_EMP_SSN_ARRAY(V_INT) := V_RIGHT_ARRAY(V_RIGHT);
END LOOP;
RETURN V_EMP_SSN_ARRAY;
END;
END PG_MERGESORT;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: