輸入乙個長度為n的整數數列,從小到大輸出前m小的數。
輸入格式
第一行包含整數n和m。
第二行包含n個整數,表示整數數列。
輸出格式
共一行,包含m個整數,表示整數數列中前m小的數。
資料範圍
1≤m≤n≤10^5,
1≤數列中元素≤10^9
輸入樣例:
5 34 5 1 3 2
輸出樣例:
1 2 3
演算法的基本思想:
按完全二叉樹存放資料,則資料中x的左二子為2x,右兒子為2x+1的關係,利用down(向下移動)、up(向上移動)函式實現題目要求。
求最小值: heap[1];
插入:heap[++size] = x; up[size];
刪除最小值: heap[1] = heap[size]; size–; down(1);
刪除任意值:heap[k] = heap[size]; size–; down(k); up(k);
修改任意值:heap[k] = x; down(k); up(k);
程式**:
#include
using
namespace std;
const
int n =
100010
;int n, m, s, h[n]
;void
down
(int u)
}voidup(
int u)
}int
main()
return0;
}
維護乙個集合,初始時集合為空,支援如下幾種操作:
「i x」,插入乙個數x;
「pm」,輸出當前集合中的最小值;
「dm」,刪除當前集合中的最小值(資料保證此時的最小值唯一);
「d k」,刪除第k個插入的數;
「c k x」,修改第k個插入的數,將其變為x;
現在要進行n次操作,對於所有第2個操作,輸出當前集合的最小值。
輸入格式
第一行包含整數n。
接下來n行,每行包含乙個操作指令,操作指令為」i x」,」pm」,」dm」,」d k」或」c k x」中的一種。
輸出格式
對於每個輸出指令「pm」,輸出乙個結果,表示當前集合中的最小值。
每個結果佔一行。
資料範圍
1≤n≤105
−109≤x≤109
資料保證合法。
輸入樣例:
8i -10
pmi -10
d 1c 2 8
i 6pm
dm輸出樣例:
-106
程式**:
#include
#include
#include
using
namespace std;
const
int n =
100010
;int h[n]
, ph[n]
, hp[n]
, s;
//ph存放第k個插入點的下標, hp存放堆中點的插入次序
void
heap_swap
(int a,
int b)
void
down
(int u)
}voidup(
int u)
}int
main()
elseif(
!strcmp
(op,
"pm"))
printf
("%d\n"
, h[1]
);elseif(
!strcmp
(op,
"dm"))
elseif(
!strcmp
(op,
"d")
)else
}return0;
}
資料結構 堆,小頂堆,大頂堆,堆排序
堆是什麼?堆是一種特殊的完全二叉樹,就像下面這棵樹一樣 這棵樹有乙個很顯著的特點,那就是所有父結點都要比子結點要小。符合這樣要求的完全二叉樹我們成為 最小堆 反之,如果所有父結點都要比子結點大,這樣的完全二叉樹被稱為 最大堆 如果我們現在要刪除掉最小的數字,並重新插入乙個數字,再從中找出最小的數字。...
資料結構之二叉堆 構建堆,堆排序
public class heap system.out.println 原始 printheapbylevel array system.out.println 最小堆 getminheap array printheapbylevel array sort array printheapbyle...
資料結構和演算法 堆和堆排序
堆是一種特殊的樹,他有倆個要求 1 堆是乙個完全二叉樹 2 堆每乙個節點的值,都大於等於 或小於等於 其左右子樹節點的值 解釋一下 第一點,完全二叉樹就是除了最後一層,其它層的節點數都是滿的,最後一層的節點都靠左排列 每個節點都大於等於左右子樹節點的叫做大頂堆,每個節點都小於等於左右子樹節點的叫做小...