matlab实现最小堆

最小堆的含义就不多比比了。最小堆可以应用于排序 ,详情可以参考文章 堆排序  。

最小堆的基本函数包括:构造堆,调整堆,弹出堆顶元素,添加一个元素。

目录

一、数组结构的最小堆

1.向下调整堆

2.构造堆

3.弹出堆顶元素

4.添加新元素

二、结构体结构的最小堆

三、元胞数组结构的最小堆


本文使用数组a表示一个堆。a(1)是堆顶元素。a(2*i) 和 a(2*i+1) 分别是 a(i) 的左右孩子。

一、数组结构的最小堆

1.向下调整堆

           从节点 i 开始向下调整,与其左右孩子比较大小,如果左或右孩子值比它小,就交换他们的位置,然后向下迭代。

function a = shiftdown(a,i)
    n = length(a);
    if 2*i <= n && 2*i+1 <= n && i <= n  %节点 i 左右孩子都有
        if a(i) > a(2*i)
            a = swap(a,i,2*i);
            a = shiftdown(a,2*i);
        end
        if a(i) > a(2*i+1)
            a = swap(a,i,2*i+1);
            a = shiftdown(a,2*i+1);
        end
    elseif 2*i <= n                     %节点 i 只有左孩子
        if a(i) > a(2*i)
            a = swap(a,i,2*i);
            a = shiftdown(a,2*i);
        end
    end
end

2.构造堆

              从底层节点(非叶子节点)开始往上构造。

% 构造一个最小堆
function a = make_heap(a)   
    n = length(a);
    for i = n/2:-1:1
        a = shiftdown(a,i);
    end
end

3.弹出堆顶元素

           删除堆顶元素,然后从新堆顶开始向下调整。

% 弹出堆顶元素
function a = pop(a)
    a(1) = [];
    n = length(a);
    a = shiftdown(a,1);
end

4.添加新元素

           将新元素添加至数组末尾,然后向上调整。

%添加一个元素
function a = push(a,value)
    a(end+1) = value;
    n = length(a);
    while n>=2
        parent = floor(n/2);
        if a(n) < a(parent);
            a = swap(a,parent,n);
        end
        n = parent;
    end
end

 

有问题或者文章有错误,欢迎提问或指教,评论区欢迎您。 白嫖请点个赞,谢谢!

 

***************************************华丽的分割线********************************************************

二、结构体结构的最小堆

更新:   结构体数组的最小堆。结构体有两个属性( 'id' , 'd' )。 根据属性 “d” 构造最小堆。

a = [19,14,5,3,27,18,19,22,11,2];

b = [];
for i = 1:length(a)
    b(i).id = i;
    b(i).d = a(i);
end    

c = make_heap(b)

function a = swap(a,i,j)  %交换数组的两个元素 
    t = a(i);
    a(i) = a(j);
    a(j) = t;
end

% 向下调整函数
function a = shiftdown(a,i)
    n = length(a);
    if 2*i <= n && 2*i+1 <= n && i <= n
        if a(i).d > a(2*i).d
            a = swap(a,i,2*i);
            a = shiftdown(a,2*i);
        end
        if a(i).d > a(2*i+1).d
            a = swap(a,i,2*i+1);
            a = shiftdown(a,2*i+1);
        end
    elseif 2*i <= n
        if a(i).d > a(2*i).d
            a = swap(a,i,2*i);
            a = shiftdown(a,2*i);
        end
    end
end
% 构造一个最小堆
function a = make_heap(a)   
    n = length(a);
    for i = n/2:-1:1
        a = shiftdown(a,i);
    end
end

% 弹出堆顶元素
function a = pop(a)
    a(1) = [];
    n = length(a);
    a = shiftdown(a,1);
end

%添加一个元素
function a = push(a,id,value)
    n = length(a)+1;
    a(n).id = id;
    a(n).d = value;
    n = length(a);
    while n>=2
        parent = floor(n/2);
        if a(n).d < a(parent).d;
            a = swap(a,parent,n);
        end
        n = parent;
    end
end

***************************************华丽的分割线********************************************************

三、元胞数组结构的最小堆

更新:   元胞数组数组的最小堆。元胞数组元素有两个值。 根据元素第二个值的大小构造最小堆。

a = [19,14,5,3,27,18,19,22,11,2];

n = 10;
   

no = {};    %根据数组构造元胞数组no ,no元素的第一个值是a元素的下标,第二个值是a元素值
for i = 1:10
    no{i} = {i;a(i)};
end

c = make_heap(no);
c

function a = swap(a,i,j)  %交换数组的两个元素 
    t = a{i};
    a{i} = a{j};
    a{j} = t;
end

% 向下调整函数
function a = shiftdown(a,i)
    n = length(a);
    if 2*i <= n && 2*i+1 <= n && i <= n
        if cell2mat(a{i}(2)) > cell2mat(a{2*i}(2))
            a = swap(a,i,2*i);
            a = shiftdown(a,2*i);
        end
        if cell2mat(a{i}(2)) > cell2mat(a{2*i+1}(2))
            a = swap(a,i,2*i+1);
            a = shiftdown(a,2*i+1);
        end
    elseif 2*i <= n
        if cell2mat(a{i}(2)) > cell2mat(a{2*i}(2))
            a = swap(a,i,2*i);
            a = shiftdown(a,2*i);
        end
    end
end
% 构造一个最小堆
function a = make_heap(a)   
    n = length(a);
    for i = n/2:-1:1
        a = shiftdown(a,i);
    end
end

% 弹出堆顶元素
function a = pop(a)
    a(1) = [];
    n = length(a);
    a = shiftdown(a,1);
end

%添加一个元素
function a = push(a,id,value)
    n = length(a)+1;
    a{n} = {id;value};
    n = length(a);
    while n>=2
        parent = floor(n/2);
        if cell2mat(a{n}(2)) < cell2mat(a{parent}(2))
            a = swap(a,parent,n);
        end
        n = parent;
    end
end

 

你可能感兴趣的:(算法,Matlab,堆)