堆排序算法.doc_第1页
堆排序算法.doc_第2页
堆排序算法.doc_第3页
堆排序算法.doc_第4页
堆排序算法.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

堆排序算法二叉堆的定义二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足二个特性:1父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。2每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。堆的存储一般都用数组来表示堆,i结点的父结点下标就为(i 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。堆的插入每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,现在的任务是将这个新数据插入到这个有序数据中这就类似于直接插入排序中将一个数据并入到有序区间中.堆的删除按定义,堆中每次都只能删除第0个数据。为了便于重建堆,实际的操作是将最后一个数据的值赋给根结点,然后再从根结点开始进行一次从上向下的调整。调整时先在左右儿子结点中找最小的,如果父结点比这个最小的子结点还小说明不需要调整了,反之将父结点和它交换后再考虑后面的结点。相当于从根结点将一个数据的“下沉”过程堆化数组有了堆的插入和删除后,再考虑下如何对一个数据进行堆化操作。要一个一个的从数组中取出数据来建立堆吧,不用!先看一个数组,如int A = 9,12,17,30,50,20,60,65,4,49;很明显,对叶子结点来说,可以认为它已经是一个合法的堆了即20,60, 65, 4, 49都分别是一个合法的堆。只要从A4=50开始向下调整就可以了。然后再取A3=30,A2 = 17,A1 = 12,A0 = 9分别作一次向下调整操作就可以了堆排序首先可以看到堆建好之后堆中第0个数据是堆中最小的数据。取出这个数据再执行下堆的删除操作。这样堆中第0个数据又是堆中最小的数据,重复上述步骤直至堆中只有一个数据时就直接取出这个数据。由于堆也是用数组模拟的,故堆化数组后,第一次将A0与An - 1交换,再对A0n-2重新恢复堆。第二次将A0与An 2交换,再对A0n - 3重新恢复堆,重复这样的操作直到A0与A1交换。由于每次都是将最小的数据并入到后面的有序区间,故操作完成后整个数组就有序了由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作,再加上前面建立堆时N / 2次向下调整,每次调整时间复杂度也为O(logN)。二次操作时间相加还是O(N * logN)。故堆排序的时间复杂度为O(N * logN)#define _CRT_SECURE_NO_WARNINGS#include #include #include #include #define MAXSIZE 1000000/交换值void Swap(int* a, int* b)int temp = *a;*a = *b;*b = temp;/打印数组元素void PrintArr(int* arr, int length)for (int i = 0; i length; i+)printf(%d , arri);printf(n);return;long GetSysTime()struct timeb tb;ftime(&tb);return tb.time * 1000 + litm; /堆调整 大堆顶,将最大值放在根结点void BigHeadAdjust(int *arr,int index,int length)int lchild = 2 * index + 1;int rchild = 2 * index + 2;int max = index;if (lchildarrmax)max = lchild;if (rchildarrmax)max = rchild;if (max != index)Swap(&arrmax, &arrindex);BigHeadAdjust(arr, max, length);return; /堆排序,采用大顶堆 升序void HeapSort_Up(int *arr, int length)/初始化堆,将每个非叶子结点倒叙进行大顶堆调整。/循环完毕 初始大顶堆(每个根结点都比它孩子结点值大)形成for (int i = length / 2 - 1; i = 0; i-)BigHeadAdjust(arr, i, length);/printf(大堆顶初始化顺序:);/PrintArr(arr, length);/将堆顶值放到数组尾部,然后又进行大堆顶调整,一次堆调整最值就到堆顶了。 for (int i = length - 1; i = 0; i-)Swap(&arr0, &arri);BigHeadAdjust(arr, 0, i);return; /堆调整 小堆顶,将最小值放在根结点void SmallHeadAdjust(int *arr, int index, int length)int lchild = 2 * index + 1;int rchild = 2 * index + 2;int min = index;if (lchildlength&arrlchildarrmin)min = lchild;if (rchildlength&arrrchild= 0; i-)SmallHeadAdjust(arr, i, length);for (int i = length - 1; i = 0; i-)Swap(&arr0, &arri);SmallHeadAdjust(arr, 0, i);return;/希尔排序 升序/根据插入排序的原理,将原来的一个大组,采用间隔的形式分成很多小组,分别进行插入排序/每一轮结束后 继续分成更小的组进行 插入排序,直到分成的小组长度为1,说明插入排序完毕void ShellSort_Up(int* arr, int length)int increase = length;int i, j, k, temp;doincrease = increase / 3 + 1;/每个小组的长度/每个小组的第0个元素for (i = 0; i increase; i+)/对每个小组进行插入排序,因为是间隔的形式分组,每个小组下一个元素为 j+=incresefor (j = i + increase; j = 0 & temp 1); int main(int argc, char *argv)srand(size_t)time(NULL);/设置随机种子int arr10 = 6,8,2,3,9,7,4,1,5,10 ;int *arr2 = (int*)malloc(sizeof(int)*MAXSIZE);int *arr3 = (int*)malloc(sizeof(int)*MAXSIZE);/给每个元素设置一个随机值for (int i = 0; i MAXSIZE; i+)int num = rand() % MAXSIZE;arr2i = num;arr3i = num;/printf(排序前:n);/PrintArr(arr, 10);/printf(堆排序升序:n);/HeapSort_Up(arr, 10);/PrintArr(arr, 10);/printf(堆排序降序:n);/HeapSort_Down(arr, 10);/PrintArr(arr, 10); long start1 = GetSysTime();ShellSort_Up(arr2, MAXSIZE);long end1 = GetSysTime();printf(%d个元素 希尔

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论