排序算法研究
作为非计算机专业的苦比,需要从头温习一下有点模糊的排序算法:
(一)插入排序
一般的算法教科书上,第一个介绍的排序算法就是插入排序,这属于内排序( 数据量小,数据全部位于内存中)。
a. 直接插入排序
依次将待排序的记录,按照关键字的大小,插入到一个已经排序好的序列中。
void InsertSort( int *pArray, int arrayLen ) { int temp = 0; int j = 0, i = 0; for ( i = 0; i < arrayLen; ++i) { temp = pArray[i]; for ( j = i; ( j > 0 ) && ( temp < pArray[j-1] ); j-- ) { pArray[j] = pArray[j-1]; } pArray[j] = temp; } } void TestInsertSort( ) { int arr[] = { 38, 22, 97, 96, 65, 38, 58 }; InsertSort( arr, sizeof( arr )/sizeof( int ) ); assert( ( 22 == arr[0] ) && ( 38 == arr[1] ) && ( 38 == arr[2] ) ); assert( ( 58 == arr[3] ) && ( 65 == arr[4] ) && ( 96 == arr[5] ) ); assert( 97 == arr[6] ); } int main() { TestInsertSort(); return 0; }
b. 希尔排序
插入排序的高级版本就是shell(希尔)排序,以间隔gap来进行插入排序,也就是每次在gap的距离内,将gap+1的值,插入到gap中。
void ShellSort( int* pArray, int arrayLen ) { int gap = 0; int i = 0; int temp = 0; int j = 0; for ( gap = arrayLen/2 ; gap > 0; gap /= 2 ) { for (int i = 0; i < arrayLen - gap; ++i) { temp = pArray[i+gap]; for ( j = i + gap; ( j > i ) && ( temp < pArray[j-1] ); j--) { pArray[j] = pArray[j-1]; } pArray[j] = temp; } } } void TestShellSort() { int arr[] = { 38, 22, 97, 96, 65, 38, 58 }; ShellSort( arr, sizeof( arr )/sizeof( int ) ); assert( 22 == arr[0] ); assert( 38 == arr[1] ); assert( 38 == arr[2] ); assert( 58 == arr[3] ); assert( 65 == arr[4] ); assert( 96 == arr[5] ); }
(二)还是冒泡简单:
void PopSort( int* pArray, int arrLen ) { int i = 0; for ( i = 0; i < arrLen; i++ ) { for (int j = arrLen-1; j > 0; --j) { if ( pArray[j] < pArray[j-1] ) { Switch( &(pArray[j]), &(pArray[j-1] ) ); } } } } void TestPopSort() { int arr[] = { 38, 22, 97, 96, 65, 38, 58 }; PopSort( arr, sizeof( arr )/sizeof( int ) ); assert( 22 == arr[0] ); assert( 38 == arr[2] ); assert( 58 == arr[3] ); assert( 65 == arr[4] ); assert( 96 == arr[5] ); }
(三)快速排序
快速排序和冒泡排序都属于交换元素的方法,快速排序的范围大,速度比较快。时间复杂度可以达到nlogn.
void QuickSort( int* pArray, int arrLen ) { int* pHead = pArray; int* pTail = pArray + arrLen - 1; int temp = *pHea if ( arrLen <= 0 ) { return; } while( pHead != pTail ) { while ( ( pTail != pHead ) && ( *pTail >= temp ) ) { pTail--; } Switch( pHead, pTail ); while ( ( pTail != pHead ) && ( *pHead <= temp ) ) { pHead++; } Switch( pHead, pTail ); } QuickSort( pArray, pTail - pArray ); QuickSort( pTail + 1, ( pArray + arrLen - 1 ) - pTail ); }
(四)选择排序
选择排序即每次从序列里面挑出最小的值,放于序列最开始,经过序列长度个步骤之后,序列变得有序。
void ChoiceSort( int* pArray, int arrLen ) { int* pMin = NULL; int temp = 0; for ( int i = 0; i < arrLen; ++i ) { pMin = &(pArray[i]); for (int j = i; j < arrLen; ++j) { if ( *pMin > pArray[j] ) { pMin = &( pArray[j] ); } } temp = pArray[i]; pArray[i] = *pMin; *pMin = temp; } }