一个复杂的堆排序程序

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

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

 运行结果: 
 


你可能感兴趣的:(gcc,C语言,堆排序)