当前位置: 首页 > news >正文

堆的实现,堆排序,咕咕咕

1.堆的实现

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int hp;typedef struct heap
{hp* data;int size;int capacity;
}heap;
//堆的初始化
void heapinit(heap* p)
{
p->data=NULL;
p->size=0;
p->capacity=0;
}
//创建堆
heap* createheap()
{heap* newheap=(heap*)malloc(sizeof(heap));if(newheap==NULL){perror("newheap malloc");exit(1);}heapinit(newheap);return newheap;
}
//堆的销毁
void destroyheap(heap* p)
{if(p==NULL) return;free(p->data);free(p);
}
//交换
void swap(hp* a,hp* b)
{hp temp=*a;*a=*b;*b=temp;
}
//向上调整堆
void siftup(heap* h,int x)
{
while(x>0)
{int parent=(x-1)/2;if(h->data[parent]<=h->data[x]) break;swap(&h->data[parent],&h->data[x]);x=parent;
}
}
//堆的插入
void heappush(heap* p,hp x)
{if(p->size==p->capacity){int newcapacity=p->capacity==0?4:p->capacity*2;hp* newdata=(hp*)realloc(p->data,newcapacity*sizeof(hp));if(newdata==NULL){perror("newdata realloc");exit(1);}p->data=newdata;p->capacity=newcapacity;}p->data[p->size]=x;p->size++;siftup(p,p->size-1);
}
//向下调整堆
void siftdown(heap* p,hp x)
{int left=2*x+1;int right=2*x+2;int largest=x;if(left<p->size&&p->data[left]>p->data[largest])largest=left;if(right<p->size&&p->data[right]>p->data[largest])largest=right;if(largest!=x){swap(&p->data[largest],&p->data[x]);siftdown(p,largest);}
}
//删除顶堆
void heapdelete(heap* h)
{if(h->size==0) return;h->data[0]=h->data[h->size-1];h->size--;siftdown(h,0);
}
//获取堆顶元素
hp heapmax(heap* p)
{assert(p->size>0);return p->data[0];
}
//判断是否为空
int heapempty(heap* p)
{
return p->size==0;
}
//获取堆的大小
int heapsize(heap* p)
{return p->size;
}

2.堆排序

//调整堆,使其满足最大堆性质
void heapify(vector<int>& arr,int n,int i)
{int largest=i;int left=2*n+1;int right=2*n+2;if(left<n&&arr[left]>arr[largest]) largest=left;if(right<n&&arr[right]>arr[largest]) largest=right;if(largest!=i){swap(arr[i],arr[largest]);heapify(arr,n,largest);}
}
//堆排序函数
void heapsort(vector<int>& arr)
{int n=arr.size();for(int i=n/2-1;i>=0;i++){heapify(arr,n,i);}for(int i=n-1;i>0;i--){swap(arr[0],arr[i]);heapify(arr,n,i);}
}

3.树

树是一种非线性的数据结构,由n个有限结点组成。有一个特殊的结点,称为根结点,根结点没有前驱结点。

除根结点外,其余结点被分成M个互不相交的集合,T1,T2.......Tm,其中每一个集合又是一棵结构与树类似的子树,每个子树的根结点有且只有一个前驱点,可以有0个或多个后续,树是递归定义的。

树有父节点,子节点(相对的)。

结点的度:一个结点有几个孩子,就有多少度。

树的度:最大结点的度。

叶子结点:度为0的结点

分支结点:度不为0的结点。

兄弟结点:具有相同父结点的结点。

结点的层次:根为第1层,每一层递推。

树的高度:树中结点的最大层次。

结点的祖先:从根到该结点所经分支上的所有结点。

结点的子孙:以某结点为根的子树中任一结点都称为该结点的子孙。

森林:由m棵互不相交的树的集合。

树的孩子兄弟表示
struct TreeNode
{
struct Node* child;左边开始的第一个孩子结点
struct Node* brother;指向其右边的下一个兄弟结点
int data;
};

文件系统利用树形结构来组织管理文件和文件夹。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

二叉树特点:不存在度大于2的结点。子树有左右之分,是有序树。

满二叉树:若是层数为k,结点为2^k-1

(根结点层数为1,非空二叉树上i层最多2^i-1个结点)
(根结点层数为1,深度为h的二叉树的最大结点数为2^h-1)

{根结点层数为1,有n个结点的满二叉树深度h=log2(n+1)

完全二叉树:最后一层可以不满足每个结点有2个子节点,但要满足从左向右填充。其余层必须都满足满结点。

二叉树可以有顺序结构和链式结构2种

(顺序结构的实现请看上面堆的实现)!!!!!!!!!!!!!!!!!!!!!!!!!!

有n个结点的完全二叉树,每个结点标记序号,对于序号为i的结点:

若i>0,i的父结点序号:(i-1)/2,i=0则没有父结点

若2*i+1<n,左孩子序号2*i+1,否则没有。

若2*i+2<n,右孩子序号2*i+2,否则没有。

向上调整算法,先把元素插入堆的末尾,如果破坏了堆的性质,把插入的结点顺着父结点向上调整位置,时间复杂度O(nlog n).

向下调整算法,把堆顶的元素与最后一个元素互换,删除堆最后一个元素,把堆顶元素向下调整至满足堆特性,时间复杂度O(n).

具体实现看上面堆实现的代码

http://www.xdnf.cn/news/1145269.html

相关文章:

  • 【RK3576】【Android14】开发板概述
  • Node.js链接MySql
  • 数据结构-3(双向链表、循环链表、栈、队列)
  • 进阶数据结构:红黑树
  • uniapp 动态控制横屏(APP 端)
  • spring boot 实战之分布式锁
  • linux 的list_for_each_entry
  • 数字化转型:概念性名词浅谈(第三十一讲)
  • 怎么判断一个对象是不是vue的实例
  • STM32-CAN
  • 根据用户id自动切换表查询
  • STM32 RTOS 开发基础:从任务管理到同步机制的全面解析
  • Git 团队协作完全指南:从基础到高级应用
  • Docker面试题
  • 饿了么app 抓包 hook
  • HTTP 性能优化:五条建议
  • 控制鼠标和键盘
  • uniapp微信小程序 实现swiper与按钮实现上下联动
  • SymAgent(神经符号自学习Agent)
  • 光伏财务管理:在阳光与资本的精密计算中前行
  • MyBatis缓存实战指南:一级与二级缓存的深度解析与性能优化
  • 用线性代数推导码分多址(CDMA)
  • vscode 一直连不上远程,网络是通的,ssh 也能直接登录远程
  • 【Linux】Linux异步IO-io_uring
  • 【Unity】IEnumeratorCoroutine
  • Ubuntu系统下交叉编译Android的X265库
  • Leetcode 04 java
  • cartorgapher的编译与运行
  • 网工知识——vlan技术
  • Linux操作系统之线程:分页式存储管理