C语言数据结构堆的基本操作实现

目录
  • 1.基本函数实现
    • a.代码1(向下调整)
    • b.代码2(向上调整)
    • c.代码3(交换)
  • 2.建堆 
  • 3.插入数据
  • 4. 删除数据
  • 5.获取堆顶的数据
  • 6.堆的数据个数
  • 7.判空
  • 8.打印
  • 9.销毁
  • 10.测试
  • 11.测试结果
  • 12.用堆排序(降序)

1.基本函数实现

a.代码1(向下调整)

void AdjustDown(DateType*a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child<n)
	{
		if ((child+1) < n && a[child] > a[child + 1])
		{
			++child;
		}
		if (a[parent] > a[child])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

注意:if里面的条件语句(child +1)<n是防止越界的,因为不能保证有右孩子。

b.代码2(向上调整)

void AdjustUp(DateType*a , int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

注意:while里面的条件语句是不能够写成(parent<0),因为当child==0时,parent=(child - 1) / 2,parent==0,再次进入循环不满足a[child] < a[parent],恰好跳出循环。如果写成(a[child] <= a[parent])就死循环了

c.代码3(交换)

void Swap(DateType*p1, DateType*p2)
{
	DateType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

2.建堆 

void CreatHeap(Heap*p,DateType*num,int n)
{
	assert(p);
	p->a = (DateType*)malloc(n * sizeof(DateType));
	if (p->a == NULL)
	{
		printf("malloc failed\n");
		exit(-1);
	}
	memcpy(p->a, num, n * sizeof(DateType));
	p->size = n;
	p->capacity = n;
	//建小堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(p->a, p->size, i);
	}
}

3.插入数据

void HeapPush(Heap*p, DateType x)
{
	assert(p);
	if (p->size == p->capacity)
	{
		DateType*tmp = (DateType*)realloc(p->a, (p->capacity) * 2 * sizeof(DateType));
		if (tmp == NULL)
		{
			printf("realloc  failed\n ");
			exit(-1);
		}
	}
	(p->capacity) *= 2;
	p->a[p->size] = x;
	++(p->size);
	//向上调整
	AdjustUp(p->a, p->size-1);
}

4. 删除数据

void HeapPop(Heap*p, DateType x)
{
	assert(p);
	Swap(&p->a[0], &p->a[p->size-1]);
	--(p->size);
	AdjustDown(p->a, p->size, 0);
	//左右子树还是小堆,直接调整行了
}

把堆顶的数据与最后一个数据交换,再次调整size-1个数据。 

5.获取堆顶的数据

DateType HeapTop(Heap*p)
{
	assert(p);
	return p->a[0];
}

6.堆的数据个数

int HeapSize(Heap*p)
{
	assert(p);
	return p->size;
}

7.判空

bool HeapIsEmpty(Heap*p)
{
	assert(p);
	return p->size == 0;
}

8.打印

void Print(Heap*p)
{
	assert(p);
	for (int i = 0; i < p->size; i++)
	{
		printf("%d ", (p->a)[i]);
	}
	printf("\n");
	int count = 0;//计数
	int levelsize = 1;
	for (int i = 0; i < p->size; i++)
	{
		printf("%d ", p->a[i]);
		++count;
		if (count == levelsize)
		{
			printf("\n");
			levelsize *= 2;
			count = 0;//重新计数
		}
	}
	printf("\n");
}

9.销毁

void HeapDestory(Heap*p)
{
	assert(p);
	free(p->a);
	p->a = NULL;
	p->capacity = p->size = 0;
}

10.测试

int main()
{
	int num[] = { 12,15,17,23,10,25 };
	int n = sizeof(num) / sizeof(num[0]);
	Heap a;
 	//创建小堆
	CreatHeap(&a,num, n);
	Print(&a);
	printf("\n");
	//插入数据
	HeapPush(&a, 1);
	Print(&a);
 	//删除对顶的数据
	HeapPop(&a);
	Print(&a);
	printf("\n");
	//获取堆顶数据
	int ret=HeapTop(&a);
	printf("The top date is %d\n",ret);
	//堆的数据个数
	int number=HeapSize(&a);
	printf("The number of heap is %d\n", number);
	//销毁
	HeapDestory(&a);
	return 0;
}

11.测试结果

12.用堆排序(降序)

a.代码1

int main()
{
	DateType num[] = { 12,15,17,23,10,25 };
	int n = sizeof(num) / sizeof(num[0]);
	HeapSort(num, n);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", num[i]);
	}
	printf("\n\n");
	return 0;
}
 
void HeapSort(int*num, int n)
{
	//建小堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(num, n, i);
	}
	int end = n - 1;
	while (end>0)
	{
		Swap(&num[0], &num[end]);
		AdjustDown(num, end, 0);
		--end;
	}
}

运行结果

堆的基本操作今天就分享在到这里了,谢谢你的浏览,如果对你有帮助的话请大家以后多多支持我们!

(0)

相关推荐

  • 数据结构之堆详解

    1. 概述 堆(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆).它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等. 2. 堆的基本操作 堆是一棵完全二叉树,高度为O(lg n),其基本操作至多与树的高度成正比.在介绍堆的基本操作之前,先介绍几个基本术语: A:用于表示堆的数组,下标从1开始,一直到n PARENT(t):节点t的父节点,即floor(t/2) RIGHT(t):节点t的左孩子节点,即:2*t LEFT(t

  • C语言数据结构之堆排序源代码

    本文实例为大家分享了C语言堆排序源代码,供大家参考,具体内容如下 1. 堆排序 堆排序的定义及思想可以参考百度百科: 用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大的数字选择出来,而且把排序过程中的一些操作进行了记录,这样在后续排序中可以利用,并且有分组的思想在里面,从而提高了排序效率,其效率为O(n*logn). 2. 源代码 堆排序中有两个核心的操作,一个是创建大顶堆(或者小顶堆,这里用的是大顶堆),再一个就是对堆进行调整.这里需要注意的是,并没有真

  • C语言对栈的实现基本操作

    c语言中栈是一种数据结构,后进先出,即最后进入栈的数据最先弹出.c语言中没有栈这种数据类型,需要自己编程构建.下面我们就一起来了解一下c语言中栈的基本操作. C语言对栈的实现基本操作,操作如下: #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <stdbool.h> typedef struct Node { int data; struct Node * pNext;

  • C语言 深入解读数据结构之堆的实现

    堆的概念与结构 概念:如果有一个关键码的集合K={ k0,k1 ,k2 ,-,kn-1 },把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足K i<=K 2*i+1且Ki<=K 2*i+2(K i>=K 2*i+1且Ki>=K 2*i+2) i = 0,1,2...,则称为小堆(或大堆).将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆. 性质: 堆中某个节点的值总是不大于或不小于其父节点的值: 堆总是一棵完全二叉树. 结构: 1.大堆 2

  • C语言实现数据结构串(堆分配存储表示法)实例详解

    堆分配存储表示法 存储结构: 构建堆来存储字符串,本质上是顺序表 实现代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define STR_INIT_SIZE 100 #define STRINCREMENT 10 typedef i

  • C语言数据结构堆的基本操作实现

    目录 1.基本函数实现 a.代码1(向下调整) b.代码2(向上调整) c.代码3(交换) 2.建堆  3.插入数据 4. 删除数据 5.获取堆顶的数据 6.堆的数据个数 7.判空 8.打印 9.销毁 10.测试 11.测试结果 12.用堆排序(降序) 1.基本函数实现 a.代码1(向下调整) void AdjustDown(DateType*a, int n, int parent) { int child = parent * 2 + 1; while (child<n) { if ((ch

  • C++语言数据结构 串的基本操作实例代码

    C语言数据结构 串的基本操作实例代码 输出结果: 实现代码: #include<iostream> using namespace std; typedef int Status; #define Max 20 #define OK 1 #define ERROR 0 #define OVERLOE -2 typedef struct//堆分配表示串 { char *ch; int length; }HString; //====================================

  • C语言数据结构 双向链表的建立与基本操作

    C语言数据结构 双向链表的建立与基本操作 双向链表比单链表有更好的灵活性,其大部分操作与线性表相同.下面总结双向链表与单链表之间的不同之处及我在实现过程中所遇到的问题. 1.双向链表的建立 双向链表在初始化时,要给首尾两个节点分配内存空间.成功分配后,要将首节点的prior指针和尾节点的next指针指向NULL,这是十分关键的一步,因为这是之后用来判断空表的条件.同时,当链表为空时,要将首节点的next指向尾节点,尾节点的prior指向首节点. 2.双向链表的插入操作 由于定义双向链表时指针域中

  • C语言数据结构二叉树之堆的实现和堆排序详解

    目录 一.本章重点 二.堆 2.1堆的介绍 2.2堆的接口实现 三.堆排序 一.本章重点 堆的介绍 堆的接口实现 堆排序 二.堆 2.1堆的介绍 一般来说,堆在物理结构上是连续的数组结构,在逻辑结构上是一颗完全二叉树. 但要满足 每个父亲节点的值都得大于孩子节点的值,这样的堆称为大堆. 每个父亲节点的值都得小于孩子节点的值,这样的堆称为小堆. 那么以下就是一个小堆. 百度百科: 堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆. 若将和此次序列对应的一维数

  • C语言数据结构之堆、堆排序的分析及实现

    目录 1.堆的概念结构及分类 1.2堆的分类 1.2.1 大堆 1.2.2 小堆 2. 堆的主要接口 3.堆的实现 3.1 堆的初始化 HeapInit 3.2 堆的销毁 HeapDestory 3.3 堆的打印 HeapPrint 3.4 堆的插入元素 HeapPush   * 3.5 堆的删除元素 HeapPop  * 4.堆的应用:堆排序   *** 4.1 堆排序实现过程分析 4.3 堆排序结果演示 5.堆(小堆)的完整代码 总结  1.堆的概念结构及分类 以上这段概念描述看起来十分复杂

  • C语言数据结构之串插入操作

    C语言数据结构之串插入操作 实例代码: /* 串的堆分配存储表示 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 typedef int Status; typedef struct { char *ch; //如果是非空串,则按串长分配存储区

  • C语言数据结构之顺序数组的实现

    C语言数据结构之顺序数组的实现 以下为展示顺序数组的示例: 1.用C语言实现的版本 #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<math.h> /* floor(),ceil(),abs() */ #include<stdlib.h> /*申请和释放内存*/ #include<stdarg.h> /*可变参数*/ #define OK 1 //成功标志 #define ERROR 0 //错误标志 #d

  • C语言数据结构之动态分配实现串

    C语言数据结构之动态分配实现串 说明:堆分配存储实现串时,串并不是以'\0', 而是用数据项int length来表示的,所以和传统的c语言操作字符串有所不同. 头文件 #ifndef PILEHEAD_H_INCLUDED #define PILEHEAD_H_INCLUDED #include <stdio.h> #include <stdlib.h> typedef struct { char* ch ; int len ; }HString ; int StrAssign(

  • C语言数据结构算法之实现快速傅立叶变换

    C语言数据结构算法之实现快速傅立叶变换 本实例将实现二维快速傅立叶变换,同时也将借此实例学习用c语言实现矩阵的基本操作.复数的基本掾作,复习所学过的动态内存分配.文件操作.结构指针的函数调用等内容. 很久以来,傅立叶变换一直是许多领域,如线性系统.光学.概率论.量子物理.天线.数字图像处理和信号分析等的一个基本分析工具,但是即便使用计算速度惊人的计算机计算离散傅立叶变换所花费的时间也常常是难以接受的,因此导致了快速傅立叶变换(FFT)的产生. 本实例将对一个二维数组进行正.反快速傅立叶变换.正傅

  • C语言数据结构 栈的基础操作

    C语言数据结构 栈的基础操作 实现了栈的基本操作,包括入栈出栈,以及书上没有写的销毁栈等操作,并对代码进行了详细的注释 MyStack.h /* * Include.h * * Created on: 2016.11.23 * Author: Jack Cui */ #ifndef MYSTACK_H_ #define MYSTACK_H_ #include <stdlib.h> #include <stdio.h> #include <malloc.h> /*栈(St

随机推荐