選擇排序&&堆排序算法
1.選擇排序: 數組
介紹:選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工做原理以下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,而後,再從剩餘未排序元素中繼續尋找最小(大)元素,而後放到已排序序列的末尾。以此類推,直到全部元素均排序完畢。數據結構
步驟:假設數組array長度爲N即有數組內有N個數據未排序數據
優化
1.第一趟遍歷將這N個數據中最小的數據和array[0]交換。
spa
2.第二趟則遍歷N-1個數據,將這N-1個數據中最小的和array[1]交換(第二趟中的數組是從原數組中的array[1]開始即排除第一趟中最小的數據再進行交換)。
設計
...
code
程序實現:blog
方法1:每趟選擇最小數據進行交換排序
1 void SelectSort(int* _array, size_t _arraySize) 2 { 3 assert(_array&&_arraySize); 4 for (size_t i = 0;i < _arraySize;++i) 5 { 6 int MinIndex = i;//記錄首位置下標 7 for (size_t j = i + 1;j < _arraySize;++j) 8 { 9 if (_array[MinIndex] > _array[j])//比較首位置以後的各個元素並將最小數據的下標賦給MinIndex 10 MinIndex = j; 11 } 12 //if (MinIndex != i)//防止首元素即最小時進行交換,減小沒必要要開銷 13 swap(_array[MinIndex], _array[i]); 14 } 15 return; 16 }
方法2:與方法一相似,進行了優化,每趟將最小數據置首,將最大元素置尾索引
1 void SelectSort_optimize(int* _array, int _arraySize) 2 { 3 assert(_array&&_arraySize); 4 5 int left = 0; 6 int right = _arraySize - 1; 7 for (;left <= right;++left,--right)//每一趟找到最大值和最小值減小循環次數 8 { 9 int MinIndex = left; 10 int MaxIndex = right; 11 for (int index = left;index <= right;++index)//此時數組爲閉區間,與未優化時存在差別 12 { 13 if (_array[MinIndex] > _array[index]) 14 MinIndex = index; 15 if (_array[MaxIndex] < _array[index]) 16 MaxIndex = index; 17 } 18 if (left != MinIndex) 19 { 20 swap(_array[left], _array[MinIndex]); 21 if (left == MaxIndex)//避免若是最大值爲_array[left]時,將被上一步操做移到_array[MinIndex]後出錯 22 MaxIndex = MinIndex;//將MaxIndex更新 23 } 24 if (right != MaxIndex) 25 swap(_array[right], _array[MaxIndex]); 26 } 27 return; 28 }
效率分析:
算法穩定性:不穩定
時間複雜度:O(n^2)
空間複雜度:O(1)
2.堆排序
介紹:堆排序(Heapsort)是指利用堆積樹(堆)這種數據結構所設計的一種排序算法,它是選擇排序的一種。能夠利用數組的特色快速定位指定索引的元素。堆分爲大堆和小堆,是徹底二叉樹。升序排序時使用大堆,降序排序時使用小堆。
步驟:對數組_array進行升序排序,假設數組array長度爲N即有數組內有N個數據未排序數據
1:將_array中的N個數據構成大堆後,此時最大值即爲_array[0],而後將_array[0]與_array[N-1]交換。
2:除_array[N-1]外,其他數據繼續創建大堆後,此時最大值仍爲_array[0],而後將_array[0]與_array[N-2]交換。
...
根據下面網址演示能夠清楚理解堆排序的過程
http://www.tyut.edu.cn/kecheng1/site01/suanfayanshi/heap_sort.asp
程序實現:
1 void AdjustDown(int* _arr,size_t ParIndex,int _arrSize)//從父節點開始向下調整 2 { 3 size_t ChildIndex = ParIndex * 2 + 1;//找出父節點的左子樹下標 4 5 while (ChildIndex < _arrSize) 6 { 7 if ((_arr[ChildIndex] < _arr[ChildIndex + 1]) && ((ChildIndex + 1) < _arrSize))//找出父節點的左右子樹中的較大值的下標 8 ChildIndex++; 9 if (_arr[ParIndex] < _arr[ChildIndex]) 10 { 11 swap(_arr[ParIndex], _arr[ChildIndex]);//若是父節點數據小於子節點數據則交換 12 ParIndex = ChildIndex; //繼續調整交換後的子樹,保證堆中任意子樹均爲大堆 13 ChildIndex = ParIndex * 2 + 1; 14 } 15 else//若是_arr[ParIndex] > _arr[ChildIndex]則說明其已經爲大堆且子樹也爲大堆,跳出循環 16 break; 17 } 18 } 19 void HeapSort(int* _array, int _arraySize) 20 { 21 assert(_array&&_arraySize > 0); 22 //建堆 23 for (int i = _arraySize / 2 - 1;i >= 0;--i)//從最後一個非葉子節點開始向下調整直到根節點調整完 24 AdjustDown(_array, i, _arraySize); 25 26 for (int j = _arraySize - 1;j > 0;--j) 27 { 28 swap(_array[0], _array[j]); 29 AdjustDown(_array, 0,j); 30 } 31 return; 32 }
下面是當數組爲{3,12,24,2,6}時的排序過程
效率分析:
算法穩定性:不穩定
時間複雜度:O(n^lg n)
空間複雜度:O(1)