标签:
用堆排序的方法实现将数组中的数字从小到大排列.
编译器:gcc, 编译环境:32位系统可以正常编译; 如果是64位系统请使用 -m32参数, 或修改宏定义中的汇编代码部分.
#include<stdio.h> #include<stdlib.h> #include<strings.h> #define push(x) __asm__ volatile ("push %%eax" ::"a"(x)) #define pop() ({ register int _res; __asm__ volatile ("pop %%eax" :"=a" (_res):); _res;}) typedef struct node{ int data; int seq; struct node *left; struct node *right; }node; node *head=NULL; void exchange(node *a,node *b){ int tmp; tmp=a->data; a->data=b->data; b->data=tmp; } node *find_node(int i,node *head){ node *p=head; int digit=0; int ii=i; while (ii!=1){ push(ii&1); digit++; ii>>=1; } while(digit){ if (pop()==1){ p=p->right; }else{ p=p->left; } digit--; } return p; } int compare_up(int i){ int tmp; if (i==1) return 1; else{ if ( find_node(i/2,head)->data > find_node(i,head)->data){ tmp=find_node(i/2,head)->data; find_node(i/2,head)->data = find_node(i,head)->data; find_node(i,head)->data=tmp; return i/2; }else{ return i; } } } void adjust_up(int i){ int tmp; while(1){ tmp=compare_up(i); if (tmp==i) break; else i=tmp; } } node *compare_down(node *p){ node *tmp; if (!p){ return p; } if (p->left!=NULL && p->right!=NULL){ if (p->left->data > p->right->data){ tmp=p->right; }else{ tmp=p->left; } if (p->data > tmp->data){ exchange(p,tmp); return(tmp); } }else if (p->left==NULL && p->right!=NULL){ if (p->right->data < p->data){ exchange(p->right,p); return(p->right); } }else if (p->left!=NULL && p->right==NULL){ if (p->left->data < p->data){ exchange(p->left,p); return(p->left); } } return p; } void adjust_down(node *head){ node *tmp; node *p=head; while(1){ tmp=compare_down(p); if (tmp==p) break; else p=tmp; } printf("%d ",head->data); } void mount_node(int i,int data){ node *tmp; int digit=0; int ii=i; node *p; if (i==1){ head=(node *)malloc(sizeof(node)); if(!head){ printf("1:malloc error!\n"); return; } bzero(head,sizeof(node)); head->data=data; head->seq=i; }else{ tmp=(node *)malloc(sizeof(node)); if(!tmp){ printf("2:malloc error!\n"); return; } bzero(tmp,sizeof(node)); tmp->data=data; tmp->seq=i; while(ii!=1){ push(ii&1); digit++; ii>>=1; } digit--; p=head; while(digit){ if (pop()==1){ p=p->right; }else{ p=p->left; } digit--; } if (pop()==1){ p->right=tmp; }else{ p->left=tmp; } } } int main(void){ /*待排序目标*/ int data[]={23,45,1,-3,67,100,90,-2,1,1}; /*头节点序号为1,向后依次累加*/ int i=1; node *tmp; /*for循环建立堆*/ for(;i<=(sizeof(data)/sizeof(int));i++){ /*产生新节点,挂在完全二叉树上*/ mount_node(i,data[i-1]); /*每插入一个节点就调整一次堆,此时的调整是从当前节点往上调整*/ adjust_up(i); } i--; /*建好堆后开始输出*/ while(i){ /*由于是从头节点开始输出,每输出一个就就调整一次堆,此时的调整是从头节点往下调整*/ adjust_down(head); /*将堆中的末尾节点与头节点对调,下一次while循环则为此次变化调整堆*/ tmp=find_node(i,head); exchange(tmp,head); /*释放末尾节点*/ free(tmp); /*将末尾节点对应的父节点指针清空*/ if (i!=1){ if (i&1){ find_node(i/2,head)->right=NULL; }else{ find_node(i/2,head)->left=NULL; } } i--; } printf("\n"); }运行结果:
标签:
原文地址:http://blog.csdn.net/liutgnukernel/article/details/51353650