基于完全二叉树的堆排序(c++)

一,将数组转存为完全二叉树(未排序)

详情见之前的博文(戳这里)

二,什么是堆排序?有哪几种?

堆排序是对二叉树的排序
②类别
(一)最大堆:父亲节点的值大于或等于所有孩子节点的值
(二)最小堆:父亲节点的值小于或等于所有孩子节点的值

三,最大堆算法设计

①最大堆就是确保每个父亲节点大于两个孩子节点,故采用递归的方式,确定是否每一个父亲节点的值是否大于两个孩子节点的值,如果该父亲节点的值小于孩子节点,进行值交换。
②每次进行过值交换,产生一个新堆,就要结束递归,再对新堆进行递归。故递归函数的返回值类型为bool,递归函数如下

bool sortHeap(NODE *root)
{
    if(root->left_children !=NULL && root->left_children->i>root->i) // 左孩子节点的值大于父亲节点的值,进行值交换,并结束递归
    {
        int temp = root->left_children->i;
        root->left_children->i = root-> i;
        root->i = temp;
        return false;
    }
    if(root->right_children !=NULL && root->right_children->i>root->i)// 左孩子节点的值大于父亲节点的值,进行值交换,并结束递归
    {
        int temp = root->right_children->i;
        root->right_children->i = root-> i;
        root->i = temp;
        return false;
    }
    if(root->left_children != NULL) // 对左孩子递归
       if( !sortHeap(root->left_children) )
           return false;
    if(root->right_children != NULL) // 对右孩子递归
       if( !sortHeap(root->right_children))
           return false;

    return true; // 以当前节点为根节点的堆符合最大堆,达到局部最优解
}

如果递归返回false证明产生了新堆没有达到最大堆,故继续递归,直到返回true,代码如下:

void get_max_heap(NODE *root){
    while(true){
        if(sortHeap(root)) 
            break;  // 进行无数次递归,直到递归返回true,证明构成最大堆
    }
    cout<<"sort success"<<endl;
}

在main函数中调用,结果如图:
执行结果
main函数

int main()
{
    cout<<"array length:";
    int l,temp;
    cin>>l; //输入数组长度
  int *x = new int[l];
  for(int i = 0 ; i<l ; i++){ //初始化数组
    cout<<"no."<<i+1<<":";
    cin>>temp;
        x[i]=temp;
  }
  NODE* root = new_node(NULL); //定义根节点
  map_tree(x,root,l); //根据数组构建完全二叉树
  print_tree(root); //打印未排序的二叉树
  get_max_heap(root); //生成最大堆
  cout<<endl; //换行
  print_tree(root); //打印最大堆
}

附(所有代码)

#include <iostream>
#include <stdlib.h>
#include <string>

using namespace std;


typedef struct node{ //节点
    struct node* parent;
    int i;
    struct node* right_children;
    struct node* left_children;
}NODE;

typedef struct queue_t{ //队列
     NODE **node_list;
     int top;
     int bottom;
     int max_length;
}QUEUE;

NODE* new_node(NODE* parent); //初始化一个节点
void map_tree(int *x , NODE *root , int length); //根据数组生成完全二叉树
void print_tree(NODE* root); // 广度优先打印树
QUEUE* new_queue(int length); //初始化一个长度为length的队列
void push_queue(QUEUE *q,NODE *n);//压入队列
NODE* pop_queue(QUEUE *q);//冒出队列
void del_queue(QUEUE *q);//销毁队列
void print(NODE *parent);//深度优先打印树
bool sortHeap(NODE *root);// 最大堆的递归函数
void get_max_heap(NODE *root);//多次执行递归
int main()
{
    cout<<"array length:";
    int l,temp;
    cin>>l; //输入数组长度
  int *x = new int[l];
  for(int i = 0 ; i<l ; i++){ //初始化数组
    cout<<"no."<<i+1<<":";
    cin>>temp;
        x[i]=temp;
  }
  NODE* root = new_node(NULL); //定义根节点
  map_tree(x,root,l); //根据数组构建完全二叉树
  print_tree(root); //打印未排序的二叉树
  get_max_heap(root); //生成最大堆
  cout<<endl; //换行
  print_tree(root); //打印最大堆
}
NODE* new_node(NODE* parent){
    NODE* temp = new NODE();
    if(temp == NULL ){
        cout<<"NODE error"<<endl;
    }
    temp->parent = parent;
    temp->i=NULL;
    temp->right_children=NULL;
    temp->left_children=NULL;
    return temp;
}

void map_tree(int *x , NODE *root , int length)
{
     QUEUE *q = new_queue(100);
     push_queue(q,root);
     for(int i=0; i< length ; i++)
     {
         NODE* temp = pop_queue(q);
         temp->i = x[i];
         temp->left_children = new_node(temp);
         push_queue(q,temp->left_children);
         temp->right_children = new_node(temp);
         push_queue(q,temp->right_children);
     }
     while(true){
        NODE* temp = pop_queue(q);
        if(temp == NULL)
            break;
        else{
            NODE *parent = temp->parent;
            if(parent->left_children == temp)
              {
                  parent->left_children = NULL;
              }
             if(parent->right_children == temp)
              {
                  parent->right_children = NULL;
              }
            free(temp);

        }
     }
     del_queue(q);
}

void print_tree(NODE *root){
    int row=1;
    bool flag = true;
    QUEUE *q = new_queue(100);
    push_queue(q,root);
    while(flag){
       for(int i=0 ; i<row ; i++)
       {
           NODE *temp = pop_queue(q);
           if(temp == NULL)
           {
               flag = false;
               break;
           }
           cout<<temp->i<<" ";
           if(temp->left_children != NULL)
           push_queue(q,temp->left_children);
           if(temp->right_children != NULL)
           push_queue(q,temp->right_children);
       }
       row = 2*row;
       cout<<endl;
    }
    del_queue(q);
}

QUEUE* new_queue(int length){
    QUEUE *queue_tmp = new QUEUE();
    if(queue_tmp == NULL){
        cout<<"error"<<endl;
    }
    queue_tmp->node_list = new NODE*[length];
    if(queue_tmp->node_list == NULL){
        cout<<"error"<<endl;
    }
    queue_tmp->top = 0;
    queue_tmp->max_length=length;
    queue_tmp->bottom = 0;
    return queue_tmp;
}
void push_queue(QUEUE *q,NODE *n){
    if((q->top+1)%(q->max_length+1) == q->bottom)
        return;
    q->node_list[q->top] = n;
    q->top = (q->top+1)%(q->max_length+1);
}
NODE* pop_queue(QUEUE *q){
    if(q->bottom == q->top)
        return NULL;
    NODE *temp = q->node_list[q->bottom];
    q->bottom = (q->bottom+1)%(q->max_length+1);
    return temp;
}
void del_queue(QUEUE *q)
{
    free(q->node_list);
    free(q);
}
void print(NODE *parent)
{
    if(parent->left_children != NULL)
        print(parent->left_children);
    if(parent->right_children != NULL)
        print(parent->right_children);
    cout<<parent->i<<" ";
}
bool sortHeap(NODE *root)
{
    if(root->left_children !=NULL && root->left_children->i>root->i) // 左孩子节点的值大于父亲节点的值,进行值交换,并结束递归
    {
        int temp = root->left_children->i;
        root->left_children->i = root-> i;
        root->i = temp;
        return false;
    }
    if(root->right_children !=NULL && root->right_children->i>root->i)// 左孩子节点的值大于父亲节点的值,进行值交换,并结束递归
    {
        int temp = root->right_children->i;
        root->right_children->i = root-> i;
        root->i = temp;
        return false;
    }
    if(root->left_children != NULL) // 对左孩子递归
       if( !sortHeap(root->left_children) )
           return false;
    if(root->right_children != NULL) // 对右孩子递归
       if( !sortHeap(root->right_children))
           return false;

    return true; // 以当前节点为根节点的堆符合最大堆,达到局部最优解
}
void get_max_heap(NODE *root){
    while(true){
        if(sortHeap(root))
            break; // 进行无数次递归,直到递归返回true,证明构成最大堆
    }
    cout<<"sort success"<<endl;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值