堆的定义与操作

  如题,堆的定义与操作。

 1 #define MAXDATA 1000        /* 该值应根据具体情况定义为大于堆中所有可能元素的值 */
 2
 3 typedef struct HNode *Heap; /* 堆的类型定义 */
 4 typedef int ElememntType;    /* 堆中的元素类型 */
 5 struct HNode {
 6     ElementType *Data;        /* 存储元素的数组 */
 7     int Size;                /* 堆中当前元素个数 */
 8     int Cap;                /* 堆的最大容量 */
 9 };
10 typedef Heap MaxHeap;        /* 最大堆 */
11 typedef Heap MinHeap;         /* 最小堆 */
12
13 /* 以最大堆为例 */
14
15 MaxHeap CreateHeap(int MaxSize)
16 {
17     MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
18     /* 堆中元素下标从 1 开始 */
19     H->Data = (ElementType*)malloc( (MaxSize+1) * sizeof(ElementType) );
20     H->Size = 0;
21     H->Cap = MaxSize;
22     H->Data[0] = MAXDATA;  /* 设置 "岗哨" ,大于 堆中所有可能元素的值 */
23
24     return H;
25 }
26
27 int IsFull(MaxHeap H)
28 {
29     return ( H->Size == H->Cap );
30 }
31
32 int IsEmpty(MaxHeap H)
33 {
34     return ( H->Size == 0 );
35 }
36
37 void Insert(MaxHeap H, ElementType X)
38 {    /* 将 X 插入到 堆 H 中,调整以符合最大堆的特性 */
39     /* 其中 H->Data[0] 已经定义为哨兵 */
40     int i;
41     if ( IsFull(H) ) return; // 堆已满
42
43     i = ++H->Size;
44     for ( ; H->Data[i/2] < X; i/=2 )
45         H->Data[i] = H->Data[i/2]; // 上滤 X
46     H->Data[i] = X; // 将 X 插入
47 }
48
49 ElementType DeleteMax(MaxHeap H)
50 {/* 从最大堆H中取出键值最大的元素,并删除一个节点 */
51     int Parent, Child;
52     ElementType MaxItem, X;
53
54     /* 这里省略判断堆是否已满的代码 */
55
56     MaxItem = H->Data[1];     /* 取出根节点存放的最大值 */
57     /* 用 最大堆中最后一个元素从根节点开始向上过滤下层节点 */
58     X = H->Data[H->Size--]; /* 注意:当前堆的规模要减小 */
59     for ( Parent = 1; Parent*2 <= H->Size; Parent=Child ) {
60         Child = Parent * 2;
61         if ( (Child != H->Size) && (H->Data[Child] < H->Data[Child+1]) )
62             Child++; /* Chile 指向左右子节点的较大者 */
63         if ( X >= H->Data[Child]  ) break; /* 找到了合适位置 */
64         else /* 下滤X */
65             H->Data[Parent] = H->Data[Child];
66     }
67     H->Data[Parent] = X;
68
69     return MaxItem;
70 }
71 /* -------------建最大堆------------- */
72 void PercDown(MaxHeap H, int p)
73 {/* 下滤:将 H 中以 H->Data[p] 为根的子堆调整为最大堆 */
74     int Parent, Child;
75     ElementType X;
76
77     X = H->Data[p]; /* 取出根节点存放的值 */
78     for ( Parent = 1; Parent*2 <= H->Size; Parent=Child ) {
79         Child = Parent * 2;
80         if ( Child != H->Size && H->Data[Child] < H->Data[Child+1] )
81             Child++; /* Chile 指向左右子节点的较大者 */
82         if ( X >= H->Data[Child]  ) break; /* 找到了合适位置 */
83         else /* 下滤X */
84             H->Data[Parent] = H->Data[Child];
85     }
86     H->Data[Parent] = X;
87 }
88
89 void BuildHeap(MaxHeap H)
90 {/* 调整 H->Data[] 中的元素,使满足最大堆的有序性 */
91  /* 这里假设所有 H->Size 个元素已经存在 H->Data[] 中 */
92
93     int i;
94     /* 从最后一个节点的父节点开始,到根节点 */
95     for ( i = (H->Size)/2; i > 0; i-- )
96         PercDown(H, i);
97 }

原文地址:https://www.cnblogs.com/wgxi/p/10002905.html

时间: 2024-10-18 16:51:33

堆的定义与操作的相关文章

数据结构-堆 接口定义与实现分析(详细注释与图解)

如果想了解堆的概念,可以点击此处查看前面关于堆的定义的随笔. 堆的操作接口包括初始化堆.销毁堆.向堆中插入元素.从堆顶移除元素.堆的结点个数. 我们用heap来命名一个堆.下面是对以上接口的定义: heap_init void heap_init(Heap *heap,int (*compare)(const void key1,const void key2),void (*destroy)(void *data)); 返回值:无 描述:初始化堆heap. 在对堆执行其他操作之前,必须要对其进

Javascript Jquery 中的数组定义与操作

Javascript Jquery 中的数组定义与操作 (2012-02-15 10:28:00) 转载▼ 标签: 杂谈   1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象Javascript不支持多维数组,但是因为数组里面可以包含对象(数组也是一个对象),所以数组可以通过相互嵌套实现类似多维数组的功能 1.1 定义数组 声明有10个元素的数组 var a = new Array(10); 此时为a已经开辟了内存空间,包含10个元素,用数组名称加 [下标] 来调用,

ORACLE基本定义、操作语句

ORACLE基本定义.操作语句 一.           表 1.创建表 CREATE TABLE TAB_NAME ( COL_01  VARCHAR2(10) NOT NULL, COL_02  NUMBER(8,2), COL_03  DATE ); 2.添加主键约束 ALTER TABLE TAB_NAME ADD CONSTRAINT PK_COL_01 PRIMARY KEY(COL_01); 3.添加唯一性约束 ALTER TABLE TAB_NAME ADD CONSTRAINT

[java学习笔记]java语言基础概述之数组的定义&amp;常见操作(遍历、排序、查找)&amp;二维数组

1.数组基础 1.什么是数组:           同一类型数据的集合,就是一个容器. 2.数组的好处:           可以自动为数组中的元素从零开始编号,方便操作这些数据. 3.格式:  (一旦创建,必须明确长度)          格式1:              元素类型   [ ]  数组名  =  new  元素类型  [元素个数即数组的长度]:              示例:int[] array = new int[5];          格式2:           

简单堆的创建和操作

回顾前面的知识,我们学了二叉树,而二叉树有很多种存储方式,比如一维数组存储, 链表存储,在刚刚学习建立二叉树的时候,我们用的是链表存储的方式,也就是利用结构体定义一个二 叉树节点,然后将这些节点连接起来.现在为了更好地存储二叉树,我们学习了堆,即将二叉树存储在 一个一维数组里面,由于按照不同的存储顺序,可以将一个堆分为最大堆和最小堆. 最大堆:每个父节点必须大于左右孩子,而每个孩子所代表的子树也是最大堆 最小堆:每个父节点必须小于左右孩子,而每个孩子所代表的子树也是最小堆 那么如何将一个堆变成一

字典的定义和操作 (Python)

字典是由key and value 构成,无序结构(不想列表那样有固体位置): note:key 是唯一的,没有重复: 字典可以多级嵌套: 定义: dict1 = { # 由等式构成 dict = { "key" : "value,....} "sid170" : "hbb", # :不能写成"=" ; 结束要有 ",". 'sid171' : "zheng", 'tid' :

集合的定义,操作及运算 (Python)

集合的定义: 集合和列表([  ]) 与  字典 ( {    }) 不同,没有特别的特别的语法格式.可以使用set () 创建. 集合同字典一样是无序的.也是不具有重复性的.因此可以把列表变成集合进行去重. 集合具有特别的关系性能,交集,并集,差集等. # hanbb come on! list1 = [1,4,5,7,3,6,7,9] # 列表 s1 = set(list1) # remove repeat,such as 7 ; 自动去重 (列表转化为集合) s2 = set([1,6,0

shell数组定义和操作

这是某天晚上自己闲来没事学习solr的时候忽然看见数组的定义,想转发一个比较详细的数组操作. 1.数组定义 a=(1 2 3 4 5) echo $a 一对括号表示是数组,数组元素用"空格"符号分割开. 2.数组读取与赋值 得到长度: echo ${#a[@]}5 用${#数组名[@或*]} 可以得到数组长度 读取: echo ${a[2]} 3 echo ${a[*]} 1 2 3 4 5 用${数组名[下标]} 下标是从0开始  下标是:*或者@ 得到整个数组内容 赋值: a[1]

javascript对象定义和操作

//js对象定义有三种方式//js方法定义有三种方式 function fn(){} var fun = function(){} var fun = new function() {} //******** *********************************//<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <titl