实现堆的各种操作
2013-10-03 15:52
162 查看
#include<stdio.h> //实现堆的各种操作 加入数据 删除数据 调整堆 获取数据 //为方便编程 数组从1开始 小顶堆 int a[100]; int size = 0; int c,b; void swap(int *a,int *b) { int temp = *a; *a = *b; *b = temp; } void addAdjust(int a[],int size) { int id = size; while(id/2!=0&&a[id]<a[id/2])//向上调整直至堆顶 { swap(&a[id],&a[id/2]); id = id/2;//id 向上前进 } } void deleteAdjust(int a[]) { a[1] = a[size--]; int id = 1; int child = id*2; for(;id*2<size;id = child)//保证其至少有左儿子 { child = id*2; if(child+1<=size&&a[child]>a[child+1])//在有右儿子的前提下判断谁最小 { child +=1; } if(a[id]>a[child])//若俩儿子中最小值比父节点值小 交换 { swap(&a[id],&a[child]); } else { break; } } //id = child 这一步很巧妙的 } int main() { char s[3]; printf("请输入相关命令和数据:\n-a 添加数据\n-d 删除堆顶 \n-g 获取堆顶元素\n-p 打印堆\n-0 退出\n"); while(1) { fflush(stdin); scanf("%s",s); if(s[1]=='a') { scanf("%d",&a[++size]); addAdjust(a,size); //printf("-a\n"); } else if(s[1]=='d') { deleteAdjust(a); printf("堆顶元素已经删除成功!"); //printf("-d\n"); } else if(s[1]=='g') { printf("目前堆顶元素(即最小元素)为:%d\n",a[1]); //printf("-g\n"); } else if(s[1]=='p') { int i; for(i=1;i<=size;i++) printf("%d ",a[i]); printf("\n"); //printf("-p\n"); } else if(s[1]=='0') { break; } else { printf("命令错误\n"); printf("请输入相关命令和数据:\n-a 添加数据\n-d 删除堆顶 \n-g 获取堆顶元素\n-p 打印堆\n-0 退出\n"); } } printf("操作完成\n"); return 0; }
#include<stdio.h> //实现堆的各种操作 加入数据 删除数据 调整堆 获取数据 //为方便编程 数组从1开始 小顶堆 int a[100]; int size = 0; int c,b; void swap(int *a,int *b) { int temp = *a; *a = *b; *b = temp; } void addAdjust(int a[],int size) { int id = size; while(id/2!=0&&a[id]<a[id/2])//向上调整直至堆顶 { swap(&a[id],&a[id/2]); id = id/2;//id 向上前进 } } int max(int a,int b) { return a=a>b?a:b; } void heapAdjust(int *a,int i,int size) { int lchild = 2*i; int rchild = 2*i+1; int max = i; if(lchild<=size&&a[max]>a[lchild]) { max = lchild; } if(rchild<=size&&a[max]>a[rchild]) { max = rchild; } if(max!=i) { swap(&a[max],&a[i]); heapAdjust(a,max,size); } else return; } void deleteAdjust(int a[]) { a[1] = a[size--]; int id = 1; int child = id*2; for(;id*2<size;id = child)//保证其至少有左儿子 { child = id*2; if(child+1<=size&&a[child]>a[child+1])//在有右儿子的前提下判断谁最小 { child +=1; } if(a[id]>a[child])//若俩儿子中最小值比父节点值小 交换 { swap(&a[id],&a[child]); } else { break; } } //id = child 这一步很巧妙的 } int main() { char s[3]; printf("请输入相关命令和数据:\n-a 添加数据\n-d 删除堆顶 \n-g 获取堆顶元素\n-p 打印堆\n-0 退出\n"); while(1) { fflush(stdin); scanf("%s",s); if(s[1]=='a') { scanf("%d",&a[++size]); addAdjust(a,size); //printf("-a\n"); } else if(s[1]=='d') { /*deleteAdjust(a); printf("堆顶元素已经删除成功!"); //printf("-d\n");*/ ///* a[1] = a[size--]; heapAdjust(a,1,size); //*/ } else if(s[1]=='g') { printf("目前堆顶元素(即最小元素)为:%d\n",a[1]); //printf("-g\n"); } else if(s[1]=='p') { int i; for(i=1;i<=size;i++) printf("%d ",a[i]); printf("\n"); //printf("-p\n"); } else if(s[1]=='0') { break; } else { printf("命令错误\n"); printf("请输入相关命令和数据:\n-a 添加数据\n-d 删除堆顶 \n-g 获取堆顶元素\n-p 打印堆\n-0 退出\n"); } } printf("操作完成\n"); return 0; }
#include<stdio.h> //实现堆的各种操作 加入数据 删除数据 调整堆 获取数据 //为方便编程 数组从1开始 小顶堆 int a[100]; int size = 0; int c,b; void swap(int *a,int *b) { int temp = *a; *a = *b; *b = temp; } void addAdjust(int a[],int size) { int id = size; while(id/2!=0&&a[id]<a[id/2])//向上调整直至堆顶 { swap(&a[id],&a[id/2]); id = id/2;//id 向上前进 } } int max(int a,int b) { return a=a>b?a:b; } void heapAdjust(int *a,int i,int size) { int lchild = 2*i; int rchild = 2*i+1; int max = i; if(lchild<=size&&a[max]>a[lchild]) { max = lchild; } if(rchild<=size&&a[max]>a[rchild]) { max = rchild; } if(max!=i) { swap(&a[max],&a[i]); heapAdjust(a,max,size); } else return; } void deleteAdjust(int a[]) { a[1] = a[size--]; int id = 1; int child = id*2; for(;id*2<size;id = child)//保证其至少有左儿子 { child = id*2; if(child+1<=size&&a[child]>a[child+1])//在有右儿子的前提下判断谁最小 { child +=1; } if(a[id]>a[child])//若俩儿子中最小值比父节点值小 交换 { swap(&a[id],&a[child]); } else { break; } } //id = child 这一步很巧妙的 } void minDelete(int a[]) { int id=1; while(id*2<=size) { if(id*2+1<=size&&a[id*2]>a[id*2+1]) { a[id] = a[id*2+1]; id = id*2+1; } else { a[id] = a[id*2]; id = id*2; } } if(id!=size) { a[id] = a[size]; while(id>=1) { if(a[id/2]>a[id]) { swap(&a[id/2],&a[id]); id = id/2; } else { return; } } } } int main() { char s[3]; printf("请输入相关命令和数据:\n-a 添加数据\n-d 删除堆顶 \n-g 获取堆顶元素\n-p 打印堆\n-0 退出\n"); while(1) { fflush(stdin); scanf("%s",s); if(s[1]=='a') { scanf("%d",&a[++size]); addAdjust(a,size); //printf("-a\n"); } else if(s[1]=='d') { /*deleteAdjust(a); printf("堆顶元素已经删除成功!"); //printf("-d\n");*/ /* a[1] = a[size--]; heapAdjust(a,1,size); */ minDelete(a); size--; } else if(s[1]=='g') { printf("目前堆顶元素(即最小元素)为:%d\n",a[1]); //printf("-g\n"); } else if(s[1]=='p') { int i; for(i=1;i<=size;i++) printf("%d ",a[i]); printf("\n"); //printf("-p\n"); } else if(s[1]=='0') { break; } else { printf("命令错误\n"); printf("请输入相关命令和数据:\n-a 添加数据\n-d 删除堆顶 \n-g 获取堆顶元素\n-p 打印堆\n-0 退出\n"); } } printf("操作完成\n"); return 0; }
本次试验提供了三个进行堆删除操作的函数 分别利用了不同的方法
前两种都是通过将a[size] 与a[1] 交换或者说覆盖然后自上而下的进行调整,一个采用for循环,一个采用递归方式。
最后一种直接将堆顶默认为空 然后通过比较子树 选择堆顶 然后向下依次延伸 最后跳出循环之后判断 空出来的位置是不是a[size]
如果不是 将a[id] = a[size] 然后再向上进行调整,当然这样的话复杂度是前两种的两倍。
注意此时size是没有减小的
相关文章推荐
- 二叉查找树的各种操作C++实现
- C:C语言实现的链表及其各种链表操作
- 十字链表 邻接表实现各种操作
- java实现对文件的各种操作
- 单链表各种操作的C语言实现(一)
- LoginUtil一句代码实现各种登录验证前置操作
- 【数据结构】用C++实现单循环链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- shellapi的SHFileOperation()的外壳函数,用它可以实现各种文件操作,如文件的拷贝、删除、移动等
- C#实现几十万级数据导出Excel及Excel各种操作实例
- 通过JSCH 实现FTP各种操作
- 数据结构基础之数组实现线性表各种操作
- 用vector、 multimap、 list容器实现好友列表的各种操作 C++
- 用类封装精灵的操作,并实例化各种精灵对象 精灵的数字序号使用单例模式的数字生成器实现
- C#对XML文件的各种操作实现方法
- java实现对文件的各种操作
- java语言实现的二叉树的各种操作(包括递归与非递归遍历二叉树,求二叉树的高度,节点总数,叶子节点等)
- PHP数组游标实现对数组的各种操作详解
- 通过FTP4J 实现FTP各种操作
- PHP数组游标实现对数组的各种操作详解
- 二叉树实现(包括遍历等各种操作,递归与非递归)