排序算法总结:
1、原地排序:不需开辟额外空间,在数组本身进行排序
2、快速排序使用递归算法实现,递归 logn 层就需要 logn 层的栈空间来保存每次递归过程中的临时变量,以供递归返回的时候继续使用。
3、归并排序也使用了递归实现,额外空间应该是n+logn的,但由于logn<n,因此为O(n)
4、相等元素在排序前后相对位置未发生改变的称为稳定排序
排序算法的稳定性
排序算法的稳定性稳定排序:对于相等的元素,在排序后,原来的元素依然靠前,
注1 在n小于一定程度时,归并排序改用插入排序的融合算法,也是稳定排序.
注2 排序算法的稳定性与具体实现相关,若实现不好,可能会将插入级归并排序实现成不稳定的算法
优化~~
- 一个数组可以看成一个堆
- 最大元素应该放到数组末尾的位置
- 堆的索引是从数组0的元素开始,而非1
- parent(i) = (i-1)/2;
- left child (i) = 2*i + 1;
- right child (i) = 2*i + 2;
#include<iostream>
#include<algorithm>
using namespace std;
void __shiftDown(T arr[], int n, int k){
while(2*k+1 <= n){
int j = 2*k+1;
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 n){
//将arr数组构建成一个堆
for(int i = (n-1)/2;i >= 0; i --){//子节点开始
__shiftDown(arr, n , i);
}
for(int i = n-1;i>0;i--){
swap(arr[0], arr[i]);
__shiftDown(arr, i , 0);
}
}
int main(){
return 0;
}
索引堆
#include <iostream>
#include <cassert>
#include "SortTestHelper.h"
using namespace std;
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;
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:
IndexMaxHeap(int capacity){
data = new Item[capacity+1];
indexes = new int[capacity+1];
count = 0;
this->capacity = capacity;
}
~IndexMaxHeap(){
delete[] data;
delete[] indexes;
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
//传入的i堆用户而言,是从0索引的。
void insert(int i, Item item){
assert( count + 1 <= capacity );
assert( i + 1 >= 1 && i + 1 <= capacity );
i += 1;
data[i] = item;
indexes[count+1] = 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 extractMaxIndex(){
assert( count > 0 );
//拿到最大元素
int ret = indexes[1] - 1;
swap( indexes[1] , indexes[count] );
count--;
shiftDown(1);
return ret;
}
Item getMax(){
assert( count > 0 );
return data[indexes[1]];
}
int getMaxIndex(){
assert( count > 0 );
return indexes[1]-1;
}
Item getItem( int i ){
assert( i + 1 >= 1 && i + 1 <= capacity );
return data[i+1];
}
void change( int i , Item newItem ){
i += 1;
data[i] = newItem;
for( int j = 1 ; j <= count ; j ++ )
if( indexes[j] == i ){
shiftUp(j);
shiftDown(j);
return;
}
}
bool testIndexes(){
int *copyIndexes = new int[count+1];
for( int i = 0 ; i <= count ; i ++ )
copyIndexes[i] = indexes[i];
copyIndexes[0] = 0;
std::sort(copyIndexes, copyIndexes + count + 1);
bool res = true;
for( int i = 1 ; i <= count ; i ++ )
if( copyIndexes[i-1] + 1 != copyIndexes[i] ){
res = false;
break;
}
delete[] copyIndexes;
if( !res ){
cout<<"Error!"<<endl;
return false;
}
return true;
}
};
template<typename T>
void heapSortUsingIndexMaxHeap(T arr[], int n){
IndexMaxHeap<T> indexMaxHeap = IndexMaxHeap<T>(n);
for( int i = 0 ; i < n ; i ++ )
indexMaxHeap.insert( i , arr[i] );
assert( indexMaxHeap.testIndexes() );
for( int i = n-1 ; i >= 0 ; i -- )
arr[i] = indexMaxHeap.extractMax();
}
int main() {
int n = 1000000;
int* arr = SortTestHelper::generateRandomArray(n, 0, n);
SortTestHelper::testSort("Heap Sort Using Index-Max-Heap", heapSortUsingIndexMaxHeap, arr, n);
delete[] arr;
return 0;
}