Using templates to implement heap sorting:
How to sort user-defined types during heap sorting? (Such as Point class)
For custom types, we need to define our own set of size comparison rules, the following three methods are used
- Operator overloading (< and >)
- Namespace extensions, template specializations
- custom function object
1. Overloading comparison operators
//overload comparison operator bool operator<(const Point & amp; lhs, const Point & amp; rhs) {<!-- --> if(lhs. getDistance() < rhs. getDistance()) {<!-- --> return true; } else if(lhs. getDistance() == rhs. getDistance()) {<!-- --> if(lhs. getX() < rhs. getX()) {<!-- --> return true; } else if(lhs. getX() == rhs. getX()) {<!-- --> if(lhs. getY() < rhs. getY()) {<!-- --> return true; } else {<!-- --> return false; } } else {<!-- --> return false; } } else {<!-- --> return false; } }
2. The namespace is expanded and the template is specialized
namespace std {<!-- --> //The specialization of less in the std namespace, pay attention to the specialization of the template template<> struct less<Point> {<!-- --> bool operator()(const Point & amp; lhs, const Point & amp; rhs) const {<!-- --> if(lhs. getDistance() < rhs. getDistance()) {<!-- --> return true; } else if(lhs. getDistance() == rhs. getDistance()) {<!-- --> if(lhs. getX() < rhs. getX()) {<!-- --> return true; } else if(lhs. getX() == rhs. getX()) {<!-- --> if(lhs. getY() < rhs. getY()) {<!-- --> return true; } else {<!-- --> return false; } } else {<!-- --> return false; } } else {<!-- --> return false; } } };
3. Custom function object
//Function object struct Comparetion {<!-- --> bool operator()(const Point & amp; lhs, const Point & amp; rhs) const {<!-- --> if(lhs. getDistance() < rhs. getDistance()) {<!-- --> return true; } else if(lhs. getDistance() == rhs. getDistance()) {<!-- --> if(lhs. getX() < rhs. getX()) {<!-- --> return true; } else if(lhs. getX() == rhs. getX()) {<!-- --> if(lhs. getY() < rhs. getY()) {<!-- --> return true; } else {<!-- --> return false; } } else {<!-- --> return false; } } else {<!-- --> return false; } } };
All code
#include#include #include #include using std::cout; using std::cin; using std::endl; using std::vector; template void swap(T & amp; lhs, T & amp; rhs) { auto temp = lhs; lhs = rhs; rhs = temp; } class point { public: Point(int ix = 0, int iy = 0) : _ix(ix) , _iy(iy) { } ~Point() { } void print() const { cout << "(" << _ix << ", " << _iy << ")" << endl; } double getDistance() const { return hypot(_ix, _iy); } int getX() const { return _ix; } int getY() const { return _iy; } friend std::ostream & amp; operator<<(std::ostream & amp;os, const Point & amp;rhs); private: int _ix; int _iy; }; std::ostream & amp; operator<<(std::ostream & amp;os, const Point & amp;rhs) { os << "(" << rhs._ix << ", " < if(lhs. getDistance() < rhs. getDistance()) { return true; } else if(lhs. getDistance() == rhs. getDistance()) { if(lhs. getX() < rhs. getX()) { return true; } else if(lhs. getX() == rhs. getX()) { if(lhs. getY() < rhs. getY()) { return true; } else { return false; } } else { return false; } } else { return false; } } // function object struct comparison { bool operator()(const Point & amp; lhs, const Point & amp; rhs) const { if(lhs. getDistance() < rhs. getDistance()) { return true; } else if(lhs. getDistance() == rhs. getDistance()) { if(lhs. getX() < rhs. getX()) { return true; } else if(lhs. getX() == rhs. getX()) { if(lhs. getY() < rhs. getY()) { return true; } else { return false; } } else { return false; } } else { return false; } } }; namespace std { //Specialization of less in the std namespace, pay attention to the specialization of the template template<> struct greater { bool operator()(const Point & amp;lhs,const Point & amp;rhs) const { if(lhs. getDistance() > rhs. getDistance()) { return true; } else if(lhs. getDistance() == rhs. getDistance()) { if(lhs. getX() > rhs. getX()) { return true; } else if(lhs. getX() == rhs. getX()) { if(lhs. getY() > rhs. getY()) { return true; } else { return false; } } else { return false; } } else { return false; } } }; }//end of namespace std bool operator>(const Point & amp;lhs, const Point & amp;rhs) { if(lhs. getDistance() > rhs. getDistance()) { return true; } else if(lhs. getDistance() == rhs. getDistance()) { if(lhs. getX() > rhs. getX()) { return true; } else if(lhs. getX() == rhs. getX()) { if(lhs. getY() > rhs. getY()) { return true; } else { return false; } } else { return false; } } else { return false; } } template > class HeapSort { public: HeapSort(T *arr, size_t size, Compare); void heapAdjust(size_t, size_t, Compare &); void sort(Compare &); void print(); private: vector vec; }; template HeapSort ::HeapSort(T *arr, size_t size, Compare com) { for (size_t i = 0; i < size; i ++ ) { vec.push_back(arr[i]); } for (int i = size/2 - 1; i >= 0; i--) { heapAdjust(i, size, com); } swap(arr[0], arr[size - 1]); sort(com); } template void HeapSort ::heapAdjust(size_t adjustpos, size_t arrlen, Compare & amp; com) { size_t dad = adjustpos; size_t son = 2 * dad + 1; while(son < arrlen) { if(son + 1 < arrlen & amp; & com(vec[son], vec[son + 1])) { + + son; } if(com(vec[dad], vec[son])) { swap(vec[dad], vec[son]); dad = son; son = 2 * dad + 1; } else { break; } } } template void HeapSort ::sort(Compare & amp; com) { size_t size = vec. size(); for (size_t i = size; i > 1; i--) { heapAdjust(0, i, com); swap(vec[0], vec[i - 1]); } } template void HeapSort ::print() { for(auto & elem : vec) { cout << elem << " "; } cout << endl; } int main(int argc, char **argv) { int arr[10] = {1, 2, 6, 3, 4, 8, 5, 7, 9, 10}; HeapSort hs(arr, 10, std::less ()); hs. print(); cout << endl; Point par[5] = {{1,2}, {3,4}, {-1 ,2}, {4,5}, {2,5}}; HeapSort hsPt(par, 5, std::less ()); hsPt. print(); return 0; }
Cause analysis:
Tip: Fill in the analysis of the question here:
For example: Handler
There are two ways to send messages, namely Handler.obtainMessage()
and Handler.sendMessage()
, where obtainMessage
method When the amount of data is too large, because the size of MessageQuene
is also limited, so when the message
is not processed in time, the first transmitted data will be overwritten, and then result in data loss.
Solution:
Tip: Fill in the specific solution to this problem here:
For example: create a new Message
object, and store the read data into Message
, then mHandler.obtainMessage(READ_DATA, bytes, -1, buffer). sendToTarget();
is replaced by mHandler.sendMessage()
.