温故而知新 -> 数据结构 -> 二叉树 -> 顺序存储 ->程序实现1_利用结构体
本篇博客是基于 温故而知新 -> 数据结构 ->树 -> 二叉树 -> 顺序存储 中实现堆顺序存储 的理论知识进行程序实现!
其中实现了 堆 的 增(入堆)删(出堆)查(堆顶元素)改(没写(~ ̄▽ ̄)~),判空,打印等操作!并附带了相关实例以及对应的运行结果!
注意:其中代码有很大冗余,且未考虑性能最优,读者有兴趣可进一步精简!
具体内容如下:
(1)newHeap.h
#ifndef __NEWHEAP_H_
#define __NEWHEAP_H_
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef int HDataType;
typedef struct heap
{
HDataType *_data;
int _size;
int _capacity;
}heap;
#endif
(2)main.c
#include"newHeap.h"
void Swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
//堆的初始化
void heapInit(heap *hp)
{
if (hp == NULL)
return;
hp->_data = NULL;
hp->_size = hp->_capacity = 0;
}
//堆是否为空
int heapEmpty(heap *hp)
{
if (hp == NULL || hp->_size == 0)
return 1;
else
return 0;
}
/*向下调整 小堆 */
void shiftDown(int *arr, int n, int curPos)
{
//printf("%d ", arr[1]);
//左孩子
int child = 2 * curPos + 1;
while (child < n)
{
//从左右孩子中找到一个最小值的位置
if (((child + 1) < n) && (arr[child + 1] < arr[child]))
++child;//和右孩子进行交换
//需要调整的数据和最小值进行比较,若小于最小值,则不需要交换,反之需要交换
if (arr[child] < arr[curPos])
{
int t = arr[curPos];
arr[curPos] = arr[child];
arr[child] = t;
//更新当前位置
curPos = child;
child = 2 * curPos + 1;
}
else
break;
}
}
/*大堆 */
//void shiftDown(int *arr, int n, int curPos)
//{
// //printf("%d ", arr[1]);
// //左孩子
// int child = 2 * curPos + 1;
// while (child < n)
// {
// //从左右孩子中找到一个最小值的位置
// if (((child + 1) < n) && (arr[child + 1] > arr[child]))
// ++child;//和右孩子进行交换
// //需要调整的数据和最小值进行比较,若小于最小值,则不需要交换,反之需要交换
// if (arr[child] > arr[curPos])
// {
// int t = arr[curPos];
// arr[curPos] = arr[child];
// arr[child] = t;
//
// //更新当前位置
// curPos = child;
// child = 2 * curPos + 1;
// }
// else
// break;
//
// }
//
//}
/*向上调整 小堆*/
void shiftUp(int *arr, int n, int curPos)
{
//父节点位置
int parent = (curPos - 1) / 2;
while (curPos > 0)
{
//比较当前位置和父节点
if (arr[curPos] < arr[parent])
{
int t = arr[curPos];
arr[curPos] = arr[parent];
arr[parent] = t;
//交换结束后,更新当前位置,继续往上走
curPos = parent;
parent = (curPos - 1) / 2;
}
else
break;//结束调整
}
}
/* 大堆 */
//void shiftUp(int *arr, int n, int curPos)
//{
// //父节点位置
// int parent = (curPos - 1) / 2;
// while (curPos > 0)
// {
// //比较当前位置和父节点
// if (arr[curPos] > arr[parent])
// {
// int t = arr[curPos];
// arr[curPos] = arr[parent];
// arr[parent] = t;
//
// //交换结束后,更新当前位置,继续往上走
// curPos = parent;
// parent = (curPos - 1) / 2;
// }
// else
// break;//结束调整
// }
//
//}
void checkCapacity(heap *hp)
{
if (hp->_size == hp->_capacity)
{
hp->_capacity = hp->_capacity == 0 ? 1 : 2 * hp->_capacity;
hp->_data = (HDataType*)realloc(hp->_data, sizeof(HDataType)*hp->_capacity);
}
}
//堆的插入
void heapPush(heap *hp, HDataType val)
{
//检查容量
checkCapacity(hp);
//尾插
hp->_data[hp->_size++] = val;
//向上调整 从最后一个位置开始往上 从0开始计数
shiftUp(hp->_data, hp->_size, hp->_size - 1);
//hp->_data[hp->_size] = val;
//shiftUp(hp->_data, hp->_size+1, hp->_size);
//hp->_size++;
}
//堆的删除:删除堆顶元素 首尾交换,删除原堆顶(现堆尾)元素,然后向下调整
void heapPop(heap *hp)
{
if (hp == NULL || hp->_size == 0)
return;
//首尾交换交换
Swap(&hp->_data[0], &hp->_data[hp->_size - 1]);
//尾删
hp->_size--;
//向下调整
shiftDown(hp->_data, hp->_size, 0);
}
//获取堆顶元素
HDataType heapTop(heap *hp)
{
return hp->_data[0];
}
//建堆
void creatHeap(int *arr, int n)
{
//从最后一个非叶子节点进行向下调整
for (int i = (n - 2) / 2; i >= 0; --i)
{
shiftDown(arr, n, i);
}
}
void heapPrint(heap *hp)
{
printf("堆中内容:");
for (int i = 0; i < hp->_size; i++)
printf("%d ", hp->_data[i]);
printf("\n");
}
//堆的排序
void test()
{
//用小堆的向下调整法,实现的结果是倒序排列,由大到小
//用大堆的向下调整法,实现的结果是正序排列,由小到大
//int arr[] = { 20, 17, 4, 16, 5, 3 };
//int n = sizeof(arr) / sizeof(arr[0]);
建堆 (n - 2) / 2 此为最后一个非叶子节点的位置
//for (int i = (n - 2) / 2; i >= 0; --i)
//{
// shiftDown(arr, n, i);
//}
//printArr(arr, n);
//int end = n - 1;
//while (end > 0)
//{
// //对的删除过程
// Swap(&arr[0], &arr[end]);
// shiftDown(arr, end, 0);
// printArr(arr, end);
// --end;
//}
// hp.HeapPush(66);
// hp.HeapPrint();// 66
// hp.HeapPush(55);
// hp.HeapPrint();// 55 66
// hp.HeapPush(22);
// hp.HeapPrint();// 22 66 55
// hp.HeapPush(44);
// hp.HeapPrint();// 22 44 55 66
// hp.HeapPush(33);
// hp.HeapPrint();// 22 33 55 66 44
// hp.HeapPush(11);
// hp.HeapPrint();// 11 33 22 66 44 55
heap hp;
heapInit(&hp);
/* 实验插入 */
heapPush(&hp, 66);
heapPrint(&hp);//66
heapPush(&hp, 55);
heapPrint(&hp);//55 66
heapPush(&hp, 22);
heapPrint(&hp);//22 66 55
heapPush(&hp, 44);
heapPrint(&hp);//22 44 55 66
heapPush(&hp, 33);
heapPrint(&hp);//22 33 55 66 44
heapPush(&hp, 11);
heapPrint(&hp);//11 33 22 66 44 55
/* 实验删除 */
heapPop(&hp);
heapPrint(&hp);//22 33 55 66 44
heapPop(&hp);
heapPrint(&hp);//33 44 55 66
heapPop(&hp);
heapPrint(&hp);//44 66 55
heapPop(&hp);
heapPrint(&hp);//55 66
/* 实验堆顶 */
printf("此时堆顶元素为:%d \n", heapTop(&hp));
}
int main()
{
test();
system("pause");
return 0;
}
(3)运行结果
以上就是本篇博客内容!
侵权删~