1.选择排序
template <typename T> //选择排序
void Selectionsort(T arr[],int n){
for(int i=0;i<n;i++){
int minIndex =i;
for(int j=i+1;j<n;j++){
if(arr[j]<arr[minIndex])
minIndex = j;
}
swap(arr[i],arr[minIndex]);
}
}
2.插入排序
template <typename T> //插入排序
void Insertsort(T arr[],int n){
for(int i=1;i<n;i++){
for(int j=i;j>0;j--){ //j=1时与j=0 进行比较!
if(arr[j]<arr[j-1])
swap(arr[j],arr[j-1]);
else
break;
}
}
}
插入排序改进版-优化时间复杂度
template<typename T> // 插入排序改进
void InsertsortG(T arr[],int n){
for(int i=1;i<n;i++){
T e = arr[i];
int j;
for( j=i;j>0&&arr[j-1]>e;j--){
arr[j]=arr[j-1];
}
arr[j] = e;
}
}
3.归并排序
template<typename T> //归并排序
void meregesort(T arr[],int qaq,int qbq){
__mergesort(arr,qaq,qbq-1);
}
template<typename T>//递归对[l,r]进行排序
void __mergesort(T arr[],int l,int r){
if(l>=r)
return ;
int mid = (l+r)/2;
__mergesort(arr,l,mid);
__mergesort(arr,mid+1,r);
if(arr[mid]>arr[mid+1]) //对归并排序进行优化可加上此条件
__merge(arr,l,mid,r);
}
template<typename T>//对[l,mid]和[mid+1,r]进行归并
void __merge(T arr[],int l,int mid,int r){
T aux[r-l+1];
for(int t=l;t<=r;t++)
aux[t-l] = arr[t];
int i = l, j = mid+1;
for(int k=l;k<=r;k++){
if(i>mid){
arr[k] = aux[j-l];
j++;
}
else if(j>r){
arr[k] = aux[i-l];
i++;
}
else if(aux[i-l]<aux[j-l]){
arr[k] = aux[i-l];
i++;
}
else{
arr[k] = aux[j-l];
j++;
}
}
}
4.一般快速排序
//对arr[l,r]进行partition操作
//返回p 使得arr[l,p-1]<arr[p],arr[p+1,r]>arr[p]
template<typename T>
int _partition(T arr[],int l,int r){
swap(arr[l],arr[rand()%(r-l+1)+l]);
//对快速排序进行优化
T v = arr[l];
//arr[l+1,j]<v;arr[j+1,i] >= v
int j = l; //上述两个区间为空
for(int i= l+1;i<=r;i++){
if(arr[i]<v){
swap(arr[j+1],arr[i]);
j++;
//swap(arr[++j],arr[i]);
}
}
swap(arr[l],arr[j]);
return j;
}
template<typename T>
void __quick_sort(T arr[],int l,int r){
if(l>=r)
return;
int p = _partition(arr,l,r);
__quick_sort(arr,l,p-1);
__quick_sort(arr,p+1,r);
}
template<typename T>
void quick_sort(T arr[],int a,int b){
srand(time(NULL));//为了优化快速排序
__quick_sort(arr,a,b-1);
}
5.二路快速排序
template<typename T>
int _partition2(T arr[],int l,int r){
swap(arr[l],arr[rand()%(r-l+1)+1]);
//对快速排序进行优化
T v = arr[l];
//arr[l+1,j]=<v;arr[j+1,i] >=v
int i =l+1;
int j = r; //上述两个区间为空
while(true){
while(i<=r && arr[i]<v) i++;
while(j>=l+1 && arr[j]>v) j--;
if(i>j) break;
swap(arr[i],arr[j]);
i++;
j--;;
}
swap(arr[l],arr[j]);
return j;
}
template<typename T>
void __quick_sort2(T arr[],int l,int r){
if(l>=r)
return;
int p = _partition2(arr,l,r);
__quick_sort2(arr,l,p-1);
__quick_sort2(arr,p+1,r);
}
template<typename T>
void quick_sort2(T arr[],int a,int b){
srand(time(NULL));//为了优化快速排序
__quick_sort2(arr,a,b-1);
}
6.三路快速排序
template<typename T>
void __quick_sort3ways(T arr[],int l,int r){
if(l>=r)
return;
//partition
swap(arr[l],arr[rand()%(r-l+1)+l]);
T v =arr[l];
int lt =l;//arr[l+1..lt]<v
int gt =r+1;//arr[gt..r]>v
int i =l+1;//arr[lt+1..i]==v
while(i<gt){
if(arr[i]<v){
swap(arr[i],arr[lt+1]);
lt++;
i++;
}
else if(arr[i]>v){
swap(arr[i],arr[gt-1]);
gt--;
}
else{//arr[i]==v
i++;
}
}
swap(arr[l],arr[lt]);
__quick_sort3ways(arr,l,lt-1);
__quick_sort3ways(arr,gt,r);
}
template<typename T>
void quick_sort3ways(T arr[],int a,int b){
srand(time(NULL));
__quick_sort3ways(arr,a,b-1);
}
7.堆排序
template<typename Item>
class MaxHeap{
private:
Item *data;
int count;
int capacity;
void ShiftUp(int k){
//插入一个数据保证它是大根堆
while(k>1 && data[k/2]<data[k]){
swap(data[k/2],data[k]);
k/=2;
}
}
void ShiftDown(int k){
//调整为大根堆
while(2*k<=count){
int j = 2*k; //这个循环中data[k]和data[j]交换位置
if(j+1<=count && data[j+1] > data[j])
//判断是否有右孩子 以及 是否右孩子大于左孩子
j+=1;
if(data[k]>=data[j])
break;
//退出循环
swap(data[k],data[j]);
k = j;
}
}
public:
MaxHeap(int capacity){
data = new Item[capacity];
count = 0;
this->capacity = capacity;
}
MaxHeap(Item arr[],int n){
data = new Item[n+1];
capacity = n;
for(int i = 0 ;i < n; i++)
data[i+1]=arr[i];
count = n;
for(int i=count/2 ;i>=1;i--)
ShiftDown(i);
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
void insert(Item item){
//插入操作(调整为一个大根堆)
assert(count+1<=capacity);
data[count+1] = item;
count ++;
ShiftUp(count);
}
Item extractMax(){//取出最大值
assert(count>0);
Item ret = data[1];
swap(data[1],data[count]);
count--;
ShiftDown(1);
return ret;
}
~MaxHeap(){
delete []data;
}
};
template<typename T>
void HeapSort1(T arr[],int a,int b){//堆排序
assert(b-a>=0);
int n = b-a+1;
MaxHeap<T> maxheap = MaxHeap<T>(n);
for(int i=0;i<n;i++)
maxheap.insert(arr[i]);
//一个一个插入成为大根堆 消耗时间,新方法 heapify
for(int i=n-1;i>=0;i--)
arr[i] = maxheap.extractMax();
}
template<typename T> //heapify方法
void HeapSort2(T arr[],int a,int b){//堆排序改进
assert(b-a>=0);
int n = b-a+1;
MaxHeap<T> maxheap = MaxHeap<T>(arr,n);
for(int i=n-1;i>=0;i--)
arr[i] = maxheap.extractMax();
}
//以上堆排序 需要额外空间
template<typename T>
void __ShiftDown2(T arr[],int n,int k){
//n个元素 K索引向下
//调整为大根堆
while(2*k+1 < n){//因为数组是从0开始
int j = 2*k+1; //这个循环中data[k]和data[j]交换位置
if(j+1< n && arr[j+1] > arr[j])
//判断是否有右孩子 以及 是否右孩子大于左孩子
j+=1;
if(arr[k]>=arr[j])
break;
//退出循环
swap(arr[k],arr[j]);
k = j;
}
}
template<typename T>
void HeapSort(T arr[],int a,int b){
assert(b-a>=0);
int n = b-a+1;
// 从(最后一个元素的索引-1)/2开始
// 最后一个元素的索引 = n-1
for( int i = (n-1-1)/2 ; i >= 0 ; i -- )
__ShiftDown2(arr, n, i);
//heapify操作
for( int i = n-1; i > 0 ; i-- ){
swap( arr[0] , arr[i] );
__ShiftDown2(arr, i, 0);
}
}
//...........
//...........
//索引堆
//...........
//...........
template<typename Item>
class IndexMaxHeap{
private:
Item *data;
int *indexes;
int count;
int capacity;
void ShiftUp(int k){
//插入一个数据保证它是大根堆
while(k>1 && data[indexes[k/2]]<data[indexes[k]]){
swap(indexes[k/2],indexes[k]);
k/=2;
}
}
void ShiftDown(int k){
//调整为大根堆
while(2*k<=count){
int j = 2*k; //这个循环中data[k]和data[j]交换位置
if(j+1<=count && data[indexes[j+1]] > data[indexes[j]])
//判断是否有右孩子 以及 是否右孩子大于左孩子
j+=1;
if(data[indexes[k]]>=data[indexes[j]])
break;
//退出循环
swap(indexes[k],indexes[j]);
k = j;
}
}
public:
MaxHeap(int capacity){
data = new Item[capacity+1];
indexes = new int[capacity+1]
count = 0;
this->capacity = capacity;
}
MaxHeap(Item arr[],int n){
data = new Item[n+1];
capacity = n;
for(int i = 0 ;i < n; i++)
data[i+1]=arr[i];
count = n;
for(int i=count/2 ;i>=1;i--)
ShiftDown(i);
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
//传入的I用户是数组从0开始,其实堆从1开始
void insert(int i,Item item){
//插入操作(调整为一个大根堆)
assert(i+1>=1 && i+1<=capacity);
assert(count+1<=capacity);
i += 1;
data[i] = item;
indexes[i] = i;
count ++;
ShiftUp(count);
}
Item extractMax(){//取出最大值
assert(count>0);
Item ret = data[indexes[1]];
swap(indexes[1],indexes[count]);
count--;
ShiftDown(1);
return ret;
}
int extractMax(){//取出最大值
assert(count>0);
int ret = indexes[1]-1;
swap(indexes[1],indexes[count]);
count--;
ShiftDown(1);
return ret;
}
Item getItem(int i){
return data[i+1];
}
void change(int i,Item newItem){
//修改索引为i的Item
i += 1;
data[i] = newItem;
//找出indexes[j] = i; j表示data[i]在堆中的位置
//shiftup(j) shiftdown(j)
for(int j=1;j<=count;j++){
if(indexes[j]==i){
ShiftUP(j);
ShiftDown(j);
return;
}
}
}
~MaxHeap(){
delete []data;
delete []indexes;
}
};