-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHeapSort.sql
167 lines (161 loc) · 4.1 KB
/
HeapSort.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
-- Author: Chetan Patil
DROP TABLE IF EXISTS inputtoheap;
CREATE TABLE inputtoheap(value integer);
INSERT INTO inputtoheap VALUES(1);
INSERT INTO inputtoheap VALUES(3);
INSERT INTO inputtoheap VALUES(2);
INSERT INTO inputtoheap VALUES(0);
INSERT INTO inputtoheap VALUES(7);
INSERT INTO inputtoheap VALUES(8);
INSERT INTO inputtoheap VALUES(9);
INSERT INTO inputtoheap VALUES(11);
INSERT INTO inputtoheap VALUES(1);
INSERT INTO inputtoheap VALUES(3);
CREATE OR REPLACE FUNCTION swap(parentpos integer, elementpos integer)
RETURNS boolean AS
$$
DECLARE parentatpos integer;
elementatpos integer;
BEGIN
SELECT value INTO parentatpos FROM heap WHERE index = parentpos;
IF EXISTS( SELECT 1 FROM heap WHERE index = elementpos) THEN
SELECT value INTO elementatpos FROM heap WHERE index = element_pos;
IF (parentatpos < elementatpos) THEN
UPDATE heap SET value = elementatpos WHERE index = parentpos;
UPDATE heap SET value = parentatpos WHERE index = elementpos;
RETURN true;
END IF;
END IF;
RETURN false;
END;
$$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION insertion(element integer)
RETURNS VOID AS
$$
DECLARE parentpos integer;
pos integer;
swapped boolean;
elempresent boolean;
BEGIN
SELECT INTO elempresent EXISTS(SELECT 1 FROM heap LIMIT 1);
IF elempresent THEN
SELECT max(index) INTO pos FROM heap;
ELSE
pos := 0;
END IF;
pos := pos + 1;
INSERT INTO heap VALUES(pos, element);
IF(pos > 1)THEN
IF(pos % 2 != 0)THEN
parentpos := (pos - 1) / 2;
ELSE
parentpos := pos / 2;
END IF;
SELECT * INTO swapped FROM swap(parentpos, pos);
WHILE(swapped = true)
LOOP
pos := parentpos;
IF(pos % 2 != 0)THEN
parentpos := (pos - 1) / 2;
ELSE
parentpos := pos / 2;
END IF;
SELECT * INTO swapped FROM swap(parentpos, pos);
END LOOP;
END IF;
END;
$$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION extraction(element integer)
RETURNS VOID AS
$$
DECLARE swapped boolean;
elempos integer;
elemval integer;
leftpos integer;
leftval integer;
rightpos integer;
rightval integer;
largestpos integer;
largestval integer;
temppos integer;
BEGIN
elempos := 0;
SELECT index INTO elempos FROM heap WHERE value = element;
IF(elempos != 0) THEN
SELECT MAX(index) INTO temppos FROM heap;
IF(elempos != temppos) THEN
SELECT * INTO swapped FROM swap(temppos, elempos);
END IF;
DELETE FROM heap WHERE index = temppos;
SELECT value INTO elemval FROM heap WHERE index = elempos;
WHILE(swapped = true)
LOOP
swapped := false;
leftpos := elempos * 2;
rightpos := leftpos + 1;
SELECT value INTO leftval FROM heap WHERE index = leftpos;
SELECT value INTO rightval FROM heap WHERE index = rightpos;
largestpos := elempos;
largestval := elemval;
IF(leftpos <= temppos AND leftval > largestval) THEN
largestpos := leftpos;
largestval := leftval;
END IF;
IF(rightpos <= temppos AND rightval > largestval)THEN
largestpos := rightpos;
largestval := rightval;
END IF;
IF(largestpos != elempos) THEN
SELECT * INTO swapped FROM swap(elempos, largestpos);
elempos := largestpos;
END IF;
END LOOP;
END IF;
END;
$$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION heapsort()
RETURNS VOID AS
$$
DECLARE heapsize integer;
root integer;
element integer;
BEGIN
DROP TABLE IF EXISTS heap;
DROP TABLE IF EXISTS sortedheap;
CREATE TABLE heap(index integer, value integer, PRIMARY KEY(index));
CREATE TABLE sortedheap(index integer, value integer);
FOR element IN SELECT value FROM inputtoheap
LOOP
PERFORM insertion(element);
END LOOP;
SELECT MAX(index) INTO heapsize FROM heap;
WHILE(heapsize >= 1)
LOOP
SELECT value INTO root FROM heap WHERE index = 1;
INSERT INTO sortedheap VALUES(heapsize, root);
PERFORM extraction(root);
heapsize := heapsize - 1;
END LOOP;
END;
$$ LANGUAGE PLPGSQL;
SELECT heapsort();
SELECT * FROM sortedheap ORDER BY index ASC;
DROP TABLE IF EXISTS heap;
DROP TABLE IF EXISTS sortedheap;
DROP TABLE IF EXISTS inputtoheap;
/*
Expected output
index | value
-------+-------
1 | 0
2 | 1
3 | 1
4 | 2
5 | 3
6 | 3
7 | 7
8 | 8
9 | 9
10 | 11
(10 rows)
*/