堆排序算法
来源:互联网 发布:mac不充电 编辑:程序博客网 时间:2024/05/16 18:27
堆排序
#include <stdio.h>#define MAXE 20//线性表中最多元素个数typedef int KeyType;typedef char InfoType[10];typedef struct //记录类型{KeyType key; //关键字项 InfoType data; //其他数据项,类型为InfoType} RecType;void DispHeap(RecType R[],int i,int n)//以括号表示法输出建立的堆{if (i<=n)printf("%d",R[i].key);//输出根结点if (2*i<=n || 2*i+1<n){printf("(");if (2*i<=n)DispHeap(R,2*i,n);//递归调用输出左子树printf(",");if (2*i+1<=n)DispHeap(R,2*i+1,n);//递归调用输出右子树printf(")");}}void Sift(RecType R[],int low,int high)//调整堆{int i=low,j=2*i; //R[j]是R[i]的左孩子RecType temp=R[i];while (j<=high) {if (j<high && R[j].key<R[j+1].key) //若右孩子较大,把j指向右孩子j++; //变为2i+1 if (temp.key<R[j].key) {R[i]=R[j]; //将R[j]调整到双亲结点位置上 i=j; //修改i和j值,以便继续向下筛选 j=2*i;} else break; //筛选结束} R[i]=temp; //被筛选结点的值放入最终位置}void HeapSort(RecType R[],int n)//对R[1]到R[n]元素实现堆排序{int i;RecType temp;for (i=n/2;i>=1;i--) //循环建立初始堆Sift(R,i,n); printf(" 初始堆:");DispHeap(R,1,n);printf("\n");//输出初始堆for (i=n;i>=2;i--) //进行n-1次循环,完成推排序{ printf(" 交换%d与%d,输出%d\n",R[i].key,R[1].key,R[1].key);temp=R[1]; //将第一个元素同当前区间内R[1]对换 R[1]=R[i]; R[i]=temp; Sift(R,1,i-1); //筛选R[1]结点,得到i-1个结点的堆printf(" 筛选调整得到堆:");DispHeap(R,1,i-1);printf("\n");//输出每一趟的排序结果}}void main(){int i,k,n=10;KeyType a[]={6,8,7,9,0,1,3,2,4,5};RecType R[MAXE];for (i=1;i<=n;i++)R[i].key=a[i-1];printf("\n");printf(" 初始关键字 ");for (k=1;k<=n;k++)printf("%2d",R[k].key);printf("\n");for (i=n/2;i>=1;i--) //循环建立初始堆Sift(R,i,n); HeapSort(R,n);printf(" 最终结果 ");//输出最终结果for (k=1;k<=n;k++)printf("%d ",R[k].key);printf("\n\n");}
这里是源代码,具体算法思想是什么,我没有弄清楚,不过,我正在花时间
#include <stdio.h>void SiftDown(int R[],int i,int size){int temp;int left=2*i+1;int right=2*i+2;int largest=i;if(left<size&&R[largest]<R[left])largest=left;if(right<size&&R[largest]<R[right])largest=right;if(largest!=i){temp=R[largest];R[largest]=R[i];R[i]=temp;SiftDown(R,largest,size);}}void HeapAdjust(int array[], int i, int nLength) { int nChild; int nTemp; for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild) { // 子结点的位置=2*(父结点位置)+ 1 nChild = 2 * i + 1; // 得到子结点中较大的结点 if ( nChild < nLength-1 && array[nChild + 1] > array[nChild]) ++nChild; // 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点 if (nTemp < array[nChild]) { array[i] = array[nChild]; array[nChild]= nTemp; } else // 否则退出循环 break; } } // 堆排序算法 void HeapSort(int array[],int length) { int tmp,i; // 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素 //length/2-1是第一个非叶节点,此处"/"为整除 for (i = length / 2 - 1; i >= 0; --i) HeapAdjust(array, i, length); // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for (i = length - 1; i > 0; --i) { // 把第一个元素和当前的最后一个元素交换, // 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的 /// Swap(&array[0], &array[i]); tmp = array[i]; array[i] = array[0]; array[0] = tmp; // 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值 HeapAdjust(array, 0, i); } }void HeapSort5(int R[],int n){int i;int r;for(i=n/2-1;i>=0;--i)SiftDown(R,i,n); for(i=0;i<6;i++) printf("%d ",R[i]); for(i=n-1;i>0;--i){r=R[i];R[i]=R[0];R[0]=r;SiftDown(R,0,i);}}int main() { int i; int R[]={4,3,1,5,6,2}; for(i=0;i<6;i++) printf("%d ",R[i]); printf("\n"); //HeapSort(R,6);// for (i = 6/ 2 - 1; i >= 0; --i) // SiftDown(R, i, 6);HeapSort5(R,6); for(i=0;i<6;i++) printf("%d ",R[i]);printf("\n%d",7/2); return 0; }
堆排序的最后总结
#include <stdio.h>void SiftDown(int R[],int i,int size){int temp;int left=2*i+1;int right=2*i+2;int largest=i;if(left<size&&R[largest]<R[left])largest=left;if(right<size&&R[largest]<R[right])largest=right;if(largest!=i){temp=R[largest];R[largest]=R[i];R[i]=temp;SiftDown(R,largest,size);}}void HeapSort(int R[],int n){int i,r;for(i=n/2-1;i>=0;i--)SiftDown(R,i,n);for(i=n-1;i>0;i--){r=R[i];R[i]=R[0];R[0]=r;SiftDown(R,0,i);}}int main() { int i; int R[]={4,3,8,1,5,6,2,7}; for(i=0;i<8;i++) printf("%d ",R[i]); printf("\n"); HeapSort(R,8); for(i=0;i<8;i++) printf("%d ",R[i]); return 0; }
- 排序算法--堆排序
- 排序算法-堆排序
- 排序算法---堆排序
- 【排序算法】堆排序
- 排序算法-堆排序
- 排序算法---堆排序
- 排序算法--堆排序
- 排序算法----堆排序
- 排序算法--堆排序
- 排序算法 堆排序
- 排序算法-堆排序
- 排序算法:堆排序
- 排序算法---堆排序
- 【排序算法】堆排序
- 排序算法:堆排序
- 排序算法-堆排序
- 排序算法:堆排序
- 排序算法-堆排序
- JDBC获取新增记录的自增主键
- (DS1.4.)poj 1552 Doubles(测试组数和每组测试用例的个数不定)
- 无法启动android模拟器
- 希望和目标
- 画图
- 堆排序算法
- SQLSERVER2008安装以及配置过程中的问题
- (DS1.4.3)POJ 2739(一个数能表示成多少个连续素数之和)
- C语言 - ACM题目:第一行输入n m,第二行输入一个数列,n为数列长度,m为要插入的值,排序后输出,m n为零时退出程序
- LOVME手机
- Django 1.5.4 专题20 fabric
- hdu 3555 Bomb (数位DP)
- SCRIPT5009: “jQuery”未定义 使用VS2012自带JQUERY报错解决办法。
- 线性表- 顺序表