试题:实现堆

82 篇文章 0 订阅
46 篇文章 0 订阅

堆的实现:

#include <vector>
#include <iostream>
using namespace std;

template <typename RandomAccessIterator, typename T, typename CompareFunc>
void __push__heap(RandomAccessIterator start, RandomAccessIterator end,
                  T *, CompareFunc comp)
{
	if (end - start == 1)
	{
		return;
	}

	unsigned int parent = end - start - 1;

	while (parent > 0)
	{
		parent = (parent - 1) / 2;

		unsigned int lchild = parent * 2 + 1;
		unsigned int rchild = parent * 2 + 2;
		unsigned int max = lchild;

		if (start + rchild < end)
		{
			max = comp(*(start + lchild), *(start + rchild))
                ? rchild
                : lchild;
		}

		if (comp(*(start + parent), *(start + max)))
		{
			T temp(*(start + parent));
			*(start + parent) = *(start + max);
			*(start + max) = temp;
		}
		else
		{
			return;
		}
	}
}

template <typename RandomAccessIterator, typename CompareFunc>
void push__heap(RandomAccessIterator start, RandomAccessIterator end,
                CompareFunc comp)
{
    __push__heap(start, end, &*start, comp);
}

template <typename RandomAccessIterator, typename T>
void __push__heap(RandomAccessIterator start, RandomAccessIterator end,
                  T *)
{
    push__heap(start, end, less<T>());
}

template <typename RandomAccessIterator>
void push__heap(RandomAccessIterator start, RandomAccessIterator end)
{
    __push__heap(start, end, &*start);
}

template <typename RandomAccessIterator, typename T, typename CompareFunc>
void __adjust__heap(RandomAccessIterator start, RandomAccessIterator end,
                    unsigned int parent, T *, CompareFunc comp)
{
    unsigned int last = end - start;
    unsigned int lchild = parent * 2 + 1;
    unsigned int rchild = parent * 2 + 2;

	while (lchild < last)
	{
        unsigned int max = lchild;

		if (rchild < last)
		{
			max = comp(*(start + lchild), *(start + rchild))
                ? rchild
                : lchild;
		}

		if (comp(*(start + parent), *(start + max)))
		{
			T temp(*(start + parent));
			*(start + parent) = *(start + max);
			*(start + max) = temp;

			parent = max;
			lchild = parent * 2 + 1;
			rchild = parent * 2 + 2;
		}
		else
		{
			return;
		}
	}
}

template <typename RandomAccessIterator, typename T, typename CompareFunc>
void __pop__heap(RandomAccessIterator start, RandomAccessIterator end,
                 T *, CompareFunc comp)
{
	--end;

	T temp(*start);
	*start = *end;
	*end = temp;

	__adjust__heap(start, end, 0, &*start, comp);
}

template <typename RandomAccessIterator, typename CompareFunc>
void pop__heap(RandomAccessIterator start, RandomAccessIterator end,
               CompareFunc comp)
{
	__pop__heap(start, end, &*start, comp);
}

template <typename RandomAccessIterator, typename T>
void __pop__heap(RandomAccessIterator start, RandomAccessIterator end,
                 T *)
{
	pop__heap(start, end, less<T>());
}

template <typename RandomAccessIterator>
void pop__heap(RandomAccessIterator start, RandomAccessIterator end)
{
	__pop__heap(start, end, &*start);
}

template <typename RandomAccessIterator, typename CompareFunc>
void sort__heap(RandomAccessIterator start, RandomAccessIterator end,
                CompareFunc comp)
{
	while (end - start > 1)
	{
		__pop__heap(start, end, &*start, comp);
		--end;
	}
}

template <typename RandomAccessIterator, typename T>
void __sort__heap(RandomAccessIterator start, RandomAccessIterator end,
                  T *)
{
	sort__heap(start, end, less<T>());
}

template <typename RandomAccessIterator>
void sort__heap(RandomAccessIterator start, RandomAccessIterator end)
{
	__sort__heap(start, end, &*start);
}

template <typename RandomAccessIterator, typename CompareFunc>
void make__heap(RandomAccessIterator start, RandomAccessIterator end,
                CompareFunc comp)
{
	if (end - start <= 1)
	{
		return;
	}

	unsigned int parent = (end - start - 2) / 2;

	while (parent > 0)
	{
		__adjust__heap(start, end, parent, &*start, comp);
		--parent;
	}
    __adjust__heap(start, end, 0, &*start, comp);
}

template <typename RandomAccessIterator, typename T>
void __make__heap(RandomAccessIterator start, RandomAccessIterator end,
                  T *)
{
    make__heap(start, end, less<T>());
}

template <typename RandomAccessIterator>
void make__heap(RandomAccessIterator start, RandomAccessIterator end)
{
    __make__heap(start, end, &*start);
}

测试代码:

template <typename CompareFunc>
void test(const char * msg, CompareFunc comp)
{
    /* Test Heap with comp */
    cout << endl << msg << endl;
    cout << "******* ====> *******" << endl;
	// test with vector
	{
		int ia[9] = { 0, 1, 2, 3, 4, 8, 9, 3, 5 };
		vector<int> ivec(ia, ia + 9);

		make__heap(ivec.begin(), ivec.end(), comp);
		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;

		ivec.push_back(7);
		push__heap(ivec.begin(), ivec.end(), comp);
		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;

		pop__heap(ivec.begin(), ivec.end(), comp);
		cout << ivec.back() << endl;
		ivec.pop_back();

		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;

		sort__heap(ivec.begin(), ivec.end(), comp);
		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;
	}

	// test with array 1
	{
		int ia[9] = { 0, 1, 2, 3, 4, 8, 9, 3, 5 };
		make__heap(ia, ia + 9, comp);

		sort__heap(ia, ia + 9, comp);
		for (int i = 0; i < 9; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;

		make__heap(ia, ia + 9, comp);
		for (int i = 0; i < 9; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;

		sort__heap(ia, ia + 9, comp);
		for (int i = 0; i < 9; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;

		pop__heap(ia, ia + 9, comp);
		cout << ia[8] << endl;
	}

	// test with array 2
	{
		int ia[6] = { 4, 1, 7, 6, 2, 5 };
		make__heap(ia, ia + 6, comp);
		for (int i = 0; i < 6; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;
	}
	cout << "******* <==== *******" << endl;
}

void test(const char * msg)
{
    /* Test Heap with default comp: less<T>() */
    cout << endl << msg << endl;
    cout << "******* ====> *******" << endl;
	// test with vector
	{
		int ia[9] = { 0, 1, 2, 3, 4, 8, 9, 3, 5 };
		vector<int> ivec(ia, ia + 9);

		make__heap(ivec.begin(), ivec.end());
		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;

		ivec.push_back(7);
		push__heap(ivec.begin(), ivec.end());
		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;

		pop__heap(ivec.begin(), ivec.end());
		cout << ivec.back() << endl;
		ivec.pop_back();

		for (int i = 0; i < ivec.size(); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;

		sort__heap(ivec.begin(), ivec.end());
		for (int i = 0; i < ivec.size( ); ++i)
		{
			cout << ivec[i] << ' ';
		}
		cout << endl;
	}

	// test with array 1
	{
		int ia[9] = { 0, 1, 2, 3, 4, 8, 9, 3, 5 };
		make__heap(ia, ia + 9);

		sort__heap(ia, ia + 9);
		for (int i = 0; i < 9; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;

		make__heap(ia, ia + 9);
		for (int i = 0; i < 9; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;

		sort__heap(ia, ia + 9);
		for (int i = 0; i < 9; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;

		pop__heap(ia, ia + 9);
		cout << ia[8] << endl;
	}

	// test with array 2
	{
		int ia[6] = { 4, 1, 7, 6, 2, 5 };
		make__heap(ia, ia + 6);
		for (int i = 0; i < 6; ++i)
		{
			cout << ia[i] << ' ';
		}
		cout << endl;
	}
	cout << "******* <==== *******" << endl;
}

bool MyLessFunc(int first, int second)
{
    return (first < second);
}

struct MyLessFunctor
{
    bool operator() (int first, int second) const
    {
        return (first < second);
    }
};

int main()
{
    test("test with default compare-function");
    test("test with less<int>()", less<int>());
    test("test with greater<int>()", greater<int>());
    test("test with MyLessFunc-function", MyLessFunc);
    test("test with MyLessFunctor()", MyLessFunctor());
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值