2021-1 算法 堆排序 c++实现

伪代码

调整堆{数组首地址,数组长度,当前要调整节点下标}
    保存当前节点到temp
    建立用来寻找最小值的下标idx,初始化为左孩子
    WHILE idx 没到数组尾:
        将当前值、左孩子、右孩子三者之中的最小值的下标给idx
        IF idx 没有变化:
            BREAK
        ELSE 用idx的值覆盖掉当前节点
    把temp放到idx处

注意到调整的前提是整体是堆结构,只有一个节点需要调整。

堆排序:数组arr,长度len
    从第一个非叶子节点,向前逐个调整,自底向上

    idx=len-1    
    WHILE idx 不到开头
        将首元素和末尾元素交换
        调整{0……idx}位置的首元素

 

过程演示

代码实现

#pragma once


#include<iostream>
#include<cstdio>


using namespace std;


typedef int DataType;
const int MAX_SIZE = 9000;

struct RecordNode
{
	DataType val;
	RecordNode() {}
	RecordNode(const DataType& data) :val(data) {}
	void setVal(DataType item) {
		val = item;
	}
	void show() {
		cout << val << " ";
	}
};


class SortObject
{
public:
	int n;//记录个数
	RecordNode* record;

	SortObject(const int len, DataType* arr) :n(len) {
		record =(RecordNode*)malloc(len * sizeof(RecordNode));
		for (int i = 0; i < len; ++i)
		{
			record[i].setVal(arr[i]);
		}
	}
	~SortObject() {}

	void visit() {
		for (int i = 0; i < n; ++i)
		{
			record[i].show();
		}
		cout << endl;
	}
};
int getMin_i(SortObject * pvector, const int size,const int now_i, const int temp) {
	//size是动态的有效范围
	int ans_i = now_i;

	DataType lval = INT_MAX, rval = INT_MAX;

	int lchild= 2 * now_i + 1;
	int rchild = lchild + 1;

	if (lchild < size) {//下标合法
		lval = pvector->record[lchild].val;
		if(rchild<size) rval=pvector->record[rchild].val;
	
		if (temp > lval) {
			if (lval > rval) ans_i = rchild;
			else ans_i = lchild;
		}
		else {
			if (temp > rval) ans_i = rchild;
		}
	}

	return ans_i;
}


void  sift(SortObject * pvector, int size, int now_i)
{
	RecordNode * data = pvector->record;
	RecordNode temp = data[now_i];
	
	while (true)
	{
		int down_i=getMin_i(pvector,size, now_i,temp.val);
		if (now_i < down_i)//下沉,下标变大
		{
			data[now_i] = data[down_i]; /* 下面覆盖父亲*/
			now_i= down_i;
		}
		else  break;
	}
	data[now_i] = temp;     /* 把元素放入正确位置 */
}


/*简化版
void  sift(SortObject * pvector, int size, int now_i)
{
	RecordNode * data = pvector->record;
	RecordNode temp = data[now_i];
	int child_i = 2 * now_i + 1;//leftchild is 2*i+1
	while (child_i < size)
	{
		if ((child_i < size - 1) && (data[child_i].val > data[child_i + 1].val))
			child_i++;//right child  
		if (temp.val > data[child_i].val)
		{
			data[now_i] = data[child_i]; 
			now_i = child_i;
			child_i = 2 * now_i + 1;
		}
		else  break;
	}
	data[now_i] = temp;    
}

*/

void  heapSort(SortObject * pvector) /* 对记录R0到Rn-1进行堆排序 */
{
	int i, n; 
	RecordNode temp;
	n = pvector->n;
	RecordNode * data = pvector->record;
	for (i = n / 2 - 1; i >= 0; i--)
		sift(pvector, n, i); /* 建立初始堆 */

	for (i = n - 1; i > 0; i--)/* 进行n-1趟堆排序 */
	{ /* 当前堆顶记录和最后一个记录互换 */
		temp = data[0];
		data[0] = data[i];
		data[i] = temp;
		sift(pvector, i, 0); /* 从R0到Ri-1重建堆,即调整 */
	}
}



void test() {
	int len = 8;
	int arr[8] = { 49,38,65,97,76,13,27,50 };
	SortObject obj(len, arr);
	obj.visit();

	SortObject* ptr = &obj;
	heapSort(ptr);
	obj.visit();
}

猜你喜欢

转载自blog.csdn.net/qq_34890856/article/details/112291899