排序算法总结
《数据结构与算法分析——C++描述(第三版)》
//Sort.h
#ifndef SORT_H
#define SORT_H
#include <vector>
#include <iostream>
using namespace std;
inline int leftChild (int i)
{
return 2*i+1;
}
template <typename T>
class Sort
{
public:
explicit Sort(const vector<T>& k);//k的名称太难听了。。
void insertsort();
void mergesort();
void quicksort();
void shellsort();
void heapsort();
void print();
void restore();
protected:
void quicksort(int left, int right);
void mergesort(vector<T>& tmpArray, int left, int right);
void merge(vector<T>& tmpArray, int leftPos, int rightPos, int rightEnd);
const T& median3(int left, int right);
void percDown(int i, int n);
private:
vector<T> a;
vector<T> origin;
};
template <typename T>
Sort<T>::Sort(const vector<T> &k)
{
a = k;
origin = k;
};
template <typename T>
void Sort<T>::insertsort()
{
int j;
for(int p = 1; p < a.size(); p++)
{
T tmp = a[p];
for(j = p; j > 0 && tmp < a[j-1]; j--)
a[j] = a[j-1];
a[j] = tmp;
}
}
template<typename T>
void Sort<T>::quicksort()
{
quicksort(0, a.size()-1);
}
template <typename T>
void Sort<T>::quicksort(int left, int right)
{
if(left+2 <= right)
{
T pivot = median3(left, right);
int i = left, j = right-1;
for(; ;)
{
while(a[++i] < pivot) {}
while(pivot < a[--j]) {}
if(i < j)
swap(a[i], a[j]);
else
break;
}
swap(a[i], a[right-1]);
quicksort(left, i-1);
quicksort(i+1, right);
}
}
template <typename T>
void Sort<T>::mergesort()
{
vector<T> tmpArray(a.size());
mergesort(tmpArray, 0, a.size()-1);
}
template <typename T>
void Sort<T>::mergesort(vector<T>& tmpArray, int left, int right)
{
if(left < right)
{
int center = (left+right)>>1;
mergesort(tmpArray, left, center);
mergesort(tmpArray, center+1, right);
merge(tmpArray, left, center+1, right);
}
}
template <typename T>
void Sort<T>::shellsort()
{
for(int gap = a.size()/2; gap > 0; gap /= 2)
for(int i = gap; i < a.size(); i++)
{
T tmp = a[i];
int j = i;
for(; j >= gap && tmp < a[j-gap]; j -= gap)
a[j]= a[j-gap];
a[j] = tmp;
}
}
template <typename T>
void Sort<T>::heapsort()
{
//建堆
for(int i = a.size()/2; i >= 0; i--)
percDown(i, a.size());
for(int j = a.size()-1; j > 0; j--)
{
swap(a[0], a[j]);
percDown(0, j);
}
}
template <typename T>
void Sort<T>::percDown(int i, int n)
{
int child;
T tmp;
for(tmp = a[i]; leftChild(i) < n; i = child)
{
child = leftChild(i);
if(child != n-1 && a[child] < a[child+1])
child++;
if(tmp < a[child])
a[i] = a[child];
else
break;
}
a[i] = tmp;
}
template <typename T>
void Sort<T>::merge(vector<T> &tmpArray, int leftPos, int rightPos, int rightEnd)
{
int leftEnd = rightPos-1;
int tmpPos = leftPos;
int numElement = rightEnd-leftPos+1;
while(leftPos <= leftEnd && rightPos <= rightEnd)
if(a[leftPos] <= a[rightPos])
tmpArray[tmpPos++] = a[leftPos++];
else
tmpArray[tmpPos++] = a[rightPos++];
//copy rest of first half
while(leftPos <= leftEnd)
tmpArray[tmpPos++] = a[leftPos++];
while(rightPos <= rightEnd)
tmpArray[tmpPos++] = a[rightPos++];
//copy to
for(int i = 0; i < numElement; i++, rightEnd--)
a[rightEnd] = tmpArray[rightEnd];
}
template <typename T>
const T & Sort<T>::median3(int left, int right)
{
int center = (left+right)>>1;
if(a[center] < a[left])
swap(a[center], a[left]);
if(a[right] < a[left])
swap(a[right], a[left]);
if(a[right] < a[center])
swap(a[right], a[center]);
//将 pivot 放在 right-1位置
swap(a[center], a[right-1]);
return a[right-1];
}
template <typename T>
void Sort<T>::print()
{
for(size_t i = 0; i < a.size(); i++)
cout<<a[i]<<",";
cout<<endl;
}
template <typename T>
void Sort<T>::restore()
{
a = origin;
}
#endif // SORT_H
//main.cpp for testing
#include "Sort.h"
int main()
{
int tmp[] = {4, 6, 2, 1, 0, 7, 22, 12, 5,3 };
size_t size = sizeof(tmp)/sizeof(int);
cout<<size<<endl;
vector<int> a;
for(size_t i = 0; i < size; i++)
a.push_back(tmp[i]);
Sort<int> test(a);
cout<<"==test sorting arigthms:=="<<endl;
cout<<"test insert sort"<<endl;
cout<<"origin array"<<endl;
test.restore();
test.print();
cout<<"sorted array"<<endl;
test.insertsort();
test.print();
cout<<"test shell sort"<<endl;
cout<<"origin array"<<endl;
test.restore();
test.print();
cout<<"sorted array"<<endl;
test.shellsort();
test.print();
cout<<"test merge sort"<<endl;
cout<<"origin array"<<endl;
test.restore();
test.print();
cout<<"sorted array"<<endl;
test.mergesort();
test.print();
cout<<"test quick sort"<<endl;
cout<<"origin array"<<endl;
test.restore();
test.print();
cout<<"sorted array"<<endl;
test.quicksort();
test.print();
return 0;
}