一个复杂的堆排序程序

来源:互联网 发布:焦作淘宝线下实体店 编辑:程序博客网 时间:2024/06/08 22:32

用堆排序的方法实现将数组中的数字从小到大排列.

编译器: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");}

运行结果:


0 0
原创粉丝点击