`
flforever1213
  • 浏览: 124676 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

算法 之 堆 - 插入和删除

阅读更多

1. 插入

为了把元素x插入到堆H中,先将堆大小加1,然后将x添加到H的末尾,再根据需要,把x上移,直到满足堆特性。

如果n是新堆的大小,那么堆树的高度是log n,所以将一个元素插入大小为n的堆中所需要的时间是O(log n)。

 

过程  Insert

输入  堆H[1...n]和元素x

输出  新的堆H[1...n+1],x为其元素之一

 

算法描述

n ← n+1 {增加H的大小}

H[n] ← x

Sift-up(H, n)

 

注意这里算法描述的数组的索引都是1...n,而不是大家习惯的0...n-1。

// heap[0]用来存储数组中堆数据的长度,堆数据heap[1]...heap[heapLength]  
// 所以数组的实际长度是heapLength+1,我们只对从数组索引为1开始的heapLength个数据进行操作 
int* insertElement(int* heap, int element)
{
	int heapLength = heap[0];
	int resultHeapLength = heapLength + 1;

	// 创建一个长度为resultHeapLength+1的int数组
	int* resultHeap = (int*)malloc(sizeof(heap) * (resultHeapLength + 1));
	if (resultHeap == NULL)
		return NULL;

	resultHeap[0] = resultHeapLength;
	for (int i = 1; i <= heapLength; i++)
	{
		resultHeap[i] = heap[i];
	}

	resultHeap[resultHeapLength] = element;
	siftUp(resultHeap, resultHeapLength);

	return resultHeap;	
}

 

2. 删除

要从大小为n的堆H中删除元素H[i],可先用H[n]替换H[i],然后将堆栈大小减1,如果需要的话,根据H[i]的键值与存储在它父节点和子节点中元素键值的关系,对H[i]做Sift-up或Sift-down运算,直到满足堆特性为止。

堆树的高度是log n,所以从一个大小为n的堆栈中删除一个元素所需要的时间是O(log n)。

 

过程  Delete

输入  非空堆H[1...n]和位于1和n之间的索引i

输出  删除H[i]之后的新堆H[1...n-1]

 

算法描述

x  ← H[i]; y ← H[n]

n ← n-1 {减小H的大小}

if i = n+1 then exit {完成}

H[i] ← y

if key(y) ≥ key(x) then Sift-up(H, i)

else Sift-down(H, i)

end if

 

注意这里算法描述的数组的索引也都是1...n,而不是大家习惯的0...n-1。

// heap[0]用来存储数组中堆数据的长度,堆数据heap[1]...heap[heapLength]  
// 所以数组的实际长度是heapLength+1,我们只对从数组索引为1开始的heapLength个数据进行操作 
int* deleteElement(int* heap, int index)
{
	int heapLength = heap[0];
	if (index < 1 || index > heapLength)
		return heap;

	int x = heap[index];
	int y = heap[heapLength];

	int resultHeapLength = heapLength - 1;

	// 创建一个长度为resultHeapLength+1的int数组
	int* resultHeap = (int*)malloc(sizeof(heap) * (resultHeapLength + 1));
	if (resultHeap == NULL)
		return NULL;

	resultHeap[0] = resultHeapLength;
	for (int i = 1; i <= resultHeapLength; i++)
	{
		resultHeap[i] = heap[i];
	}

	if (index == resultHeapLength)
		return resultHeap;

	resultHeap[index] = y;
	if (y > x)
	{
		siftUp(resultHeap, index);
	}
	else
	{
		siftDown(resultHeap, index);
	}

	return resultHeap;
}

 

我使用的数组是这样定义的:

const int HEAP_LENGH = 10;
int heap[HEAP_LENGH + 1] = { HEAP_LENGH, 20, 11, 9, 10, 5, 4, 5, 3, 7, 3 };

// 如果用我上面写的方法插入删除数据,不要忘了在操作完成之后释放内存哦
int* heapAfterInsert = insertElement(heap, 30);
int* heapAfterDelete = deleteElement(heapAfterInsert, 2);
free(heapAfterDelete);
free(heapAfterInsert);

 

更多内容请参考:

算法 之 堆 - 简介

算法 之 堆 - Sift-up和Sift-down

1
3
分享到:
评论

相关推荐

    数据结构算法与应用--C++语言描述(代码与习题答案)

    链表分为单链表、双链表和循环链表等类型,提供了灵活的插入和删除操作。 3. **栈**:栈是一种后进先出(LIFO)的数据结构,常用于函数调用、表达式求值等场景。C++中的`std::stack`库提供了栈操作的实现。 4. **...

    数据结构算法与应用-C__语言描述.rar

    链表则允许动态插入和删除,适合内存管理;队列遵循先进先出(FIFO)原则,常见于任务调度;栈则是后进先出(LIFO)模型,常用于函数调用和表达式求值。 2. 树形数据结构:如二叉树、平衡树(AVL树、红黑树)和堆。...

    算法导论--教师手册

    - **散列表(Hash Tables)**:章节11介绍了散列表的概念及其应用,包括散列函数的设计、冲突解决策略等,散列表在平均情况下的查找、插入和删除操作时间复杂度均为O(1)。 - **二叉搜索树(Binary Search Trees)**...

    C 常用算法程序集-徐士良

    3. **图论与树**:可能包含图的遍历(深度优先搜索和广度优先搜索)、最小生成树(如Prim或Kruskal算法)以及二叉树的操作,如插入、删除和查找。 4. **动态规划**:这是解决许多复杂问题的有效方法,例如背包问题...

    数据结构堆的插入与删除 堆排序

    本文将详细讲解堆的初始化、插入、删除操作,以及使用C++实现的堆排序算法。 首先,堆是一种完全二叉树,可以分为最大堆和最小堆。在最大堆中,每个节点的值都大于或等于其子节点的值;在最小堆中,每个节点的值都...

    算法导论及课后习题与思考题答案(完整英文版第2版)

    该书不仅详细介绍了算法的基本概念、原理和设计策略,还提供了大量的实例分析和实践应用,使其成为计算机科学领域不可或缺的经典之作。 ### 知识点解析 #### 1. 算法基础知识 - **定义与分类**:书中首先对算法...

    数据结构与排序算法------通过代码示例,讲解:数据结构和9种排序算法。.zip

    基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法: 算法设计:研究如何将解决问题的步骤形式化为一系列指令,...

    总结专栏《数据结构与算法之美---王争》.zip

    《数据结构与算法之美》是王争先生撰写的一部深入浅出的数据结构和算法学习资料。这个压缩包可能包含了该专栏的资源文件“ljg_resource1”,虽然具体内容未知,但我们可以根据通常的数据结构和算法的学习内容进行...

    数据结构与算法分析---C语言描述

    书中涉及到的知识点包括算法分析,列表,栈和队列,树,哈希,优先队列(堆),排序算法,离散集ADT,图算法,算法设计技术,摊还分析,以及高级数据结构和实现等。 算法分析是研究算法性能的过程,它包括时间...

    B_树的插入、删除、查找的算法(C语言描述).doc

    以下是B-树的基本概念、查找算法、插入算法和删除算法的详细说明。 **基本概念:** B-树是一种m阶的树,意味着每个节点最多有m个孩子。在B-树中,节点包含关键字和指向子节点的指针。节点中的关键字按照升序排列,...

    数据结构,算法与应用 ---C++语言描述代码 (包括习题)

    书中可能涵盖排序算法(如冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序)、搜索算法(如线性搜索、二分搜索、深度优先搜索和广度优先搜索)、图算法(如Dijkstra算法、Floyd-Warshall算法、Prim算法和...

    数据结构与算法---C++版(Adam Drozdek)书中的源代码

    5. **排序算法**:排序是将无序序列转变为有序序列的过程,包括冒泡排序、插入排序、选择排序、快速排序、归并排序和堆排序等。不同的排序算法有不同的时间复杂度和适用场景,比如快速排序在平均情况下效率较高,而...

    数据结构算法与应用-C语言描述

    它们在查找、插入和删除操作中具有良好的性能。堆通常用于优先队列,可以快速找到最大或最小元素。图则用于表示复杂的关系,如网络路由、社交网络等,常见的图算法有深度优先搜索(DFS)和广度优先搜索(BFS)。 ...

    数据结构算法与应用-C/C++语言描述

    在本书中,你将学习到排序算法(如冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序)、搜索算法(线性搜索、二分搜索)、图算法(深度优先搜索、广度优先搜索)、动态规划以及贪心算法等。这些算法不仅...

    数据结构算法与应用--C++ 语言描述

    算法是数据结构的灵魂,常见算法如排序(冒泡、选择、插入、快速、归并、堆排序等)和搜索(顺序、二分、哈希)。C++中,算法通常作为独立的头文件提供,如`&lt;algorithm&gt;`,方便开发者直接调用。 在实际应用中,理解...

    数据结构算法与应用--C++语言描述(源代码)

    数据结构是计算机科学中的核心课程,它探讨了如何在计算机中有效地存储和组织数据,以便进行高效的检索、插入和删除等操作。C++语言作为面向对象的编程语言,提供了丰富的特性和工具,使得实现复杂的数据结构算法变...

    数据结构与算法-课件-代码-Python语言描述

    排序算法如冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序,各有其适用场景和优缺点。搜索算法有线性搜索、二分搜索以及哈希表搜索等,其中二分搜索适用于有序数据,而哈希表搜索则提供近乎常数时间的...

Global site tag (gtag.js) - Google Analytics