- 堆排序
堆有大顶堆和小顶堆,大顶堆是,结点≥左右孩子节点,小顶堆是节点≤左右孩子节点。
堆的存储方式可以采用顺序存储和链接存储,由于堆是一棵完全二叉树,所以采用顺序存储的方式更能充分利用存储空间,而且不通过指针通过下标建立父与子的映射关系也很方便。
现在要写一个堆的类,应该包含以下内容:
1) 初始化:需要申请内存
2)插入数据:首先判断现有内存空间是否够用,如果不够用,需要重新分配一倍的空间,再把原来的数据复制过来,并释放原有空间,在尾部插入,然后上溢
3)删除数据:将尾部数据替换该数据,删除尾部数据(数组尾部删除更容易,删除采用惰性删除),然后对该位置进行下溢;
4)销毁:需要释放内存
5)判断堆是否为空:需要一个变量记录堆中元素。#ifndef MINHEAP_MINHEAP_H #define MINHEAP_MINHEAP_H typedef int ElemType; struct Heap{ ElemType *heap; int len; int MaxSize; }; void InitHeap(Heap &HBT); void ClearHeap(Heap &HBT); bool Empty(Heap &HBT); void InsertHeap(Heap &HBT,ElemType elem); ElemType DeleteHeap(Heap &HBT); #endif //MINHEAP_MINHEAP_H
// // Created by JanzeeLiu on 2019-08-26. // #include "minheap.h" #include <iostream> using namespace std; void InitHeap(Heap &HBT){ HBT.MaxSize=10; HBT.heap=new ElemType[HBT.MaxSize]; if(HBT.heap==nullptr){//内存分配失败返回空指针 cout<<"分配内存失败"<<endl; exit(1); } HBT.len=0; } void ClearHeap(Heap &HBT){ if(HBT.heap){ delete [] HBT.heap; HBT.heap=nullptr; HBT.MaxSize=0; HBT.len=0; } } bool Empty(Heap &HBT){ return HBT.len==0; } void InsertHeap(Heap &HBT,ElemType elem){//尾部插入,上溢操作 if(HBT.len==HBT.MaxSize){//内存占满,重新分配一倍空间 int k=sizeof(ElemType); HBT.heap=(ElemType *)realloc(HBT.heap,2*HBT.MaxSize*k); if(HBT.heap==nullptr){ cout<<"分配内存失败"<<endl; exit(1); } HBT.MaxSize*=2; } if(HBT.len==0){ HBT.heap[0]=elem; ++HBT.len; return; } int i=HBT.len; while(i>0){ int j=(i-1)/2; if(HBT.heap[j]<=elem) break; HBT.heap[i]=HBT.heap[j];//该节点存储父亲 i=j; } HBT.heap[i]=elem; ++HBT.len; } ElemType DeleteHeap(Heap &HBT){//删除堆顶元素,尾部元素替换堆顶元素,再删除尾部元素,再对堆顶进行下溢 if(HBT.len==0){ ClearHeap(HBT); cout<<"堆为空"<<endl; exit(1); } ElemType tmp=HBT.heap[0]; --HBT.len; if(HBT.len<=0) return tmp; ElemType elem=HBT.heap[HBT.len]; int i=0; int j=2*i+1; while(j<HBT.len){ if(j<HBT.len-1 && HBT.heap[j]>HBT.heap[j+1]) ++j;//有右孩子,且右孩子小于左孩子,此时的J是较小的孩子 if(HBT.heap[j]>=elem) break; HBT.heap[i]=HBT.heap[j]; i=j; j=2*i+1; } HBT.heap[i]=elem; return tmp; }
#include <iostream> #include "minheap.h" using namespace std; int main() { int a[8]={23,56,40,62,38,55,10,16}; Heap b; InitHeap(b); for(int i=0;i<8;++i){ InsertHeap(b,a[i]); } for(int i=0;i<8;++i){ cout<<b.heap[i]<<" "; } cout<<endl; while(!Empty(b)){ ElemType elem=DeleteHeap(b); cout<<elem<<" "; } return 0; }
输出结果:
10 16 23 38 56 55 40 62
10 16 23 38 40 55 56 62 - 各种排序算法时间复杂度,还问了我一个topk的问题。
冒泡排序O(n^2),插入排序≈O(n^2),选择排序O(n^2),快排O (nlogn),归并排序O(n log n),堆排序O (nlgn)。以上所说的是平均时间复杂度。 - 什么是关系型数据库?常见的关系型数据库有哪些?mysql数据库底层原理,为什么要用B+树?为什么要有索引?B+树里面存储的内容
关系型数据库就是根据关系模型建立的数据库,所谓的关系模型是指二维关系表。
表名是对该表关系的描述,一个记录对应表中一行,表有多个属性,用列表示,每一个记录有一个键值来唯一标志该记录。
常见关系型数据库有SQL Server,Mysql,Oracle,Sybase,DBII;非关系型数据库有mongoDB,redis。redis是一个key-value存储系统。 - 进程,线程介绍一下,通信方式有哪些?
- http协议讲一下,报文格式是什么?
- 两个域名a.www.com和b.www.com与一个webserver(11.1.1.1)通信,webserver如何区分这两个不用的用户?或者说如何把数据分给这两个用户。
贝壳面试
最新推荐文章于 2022-11-03 20:23:46 发布