<pre name="code" class="cpp">// Sort.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "stdio.h" #include "iostream" using namespace std; // PrintArray void PrintArray(int *arr, int length); // 直接插入排序 void InsertSort(int * arr, int length); // Binary Insert void BinaryInsert(int * arr, int length); // 希尔排序(Shell sort) void ShellSort(int * arr, int length); // Bubble Sort void BubbleSort(int * arr, int length); // Simple Select Sort void SimpleSelectSort(int * arr, int length); // Quick Sort void QuickSort(int * arr, int left, int right); int Partition(int * arr, int left, int right); // 堆排序 void HeapSort(int * arr, int length); void HeapAdjust(int * arr, int start, int length); // 归并排序 void MergeSort(int * arr, int *arr2, int left, int right); void Merge(int * arr, int *arr2, int left, int mid, int right); int _tmain(int argc, _TCHAR* argv[]) { int array[10] = {7, 2, 8, 6, 9, 1, 5, 0, 4, 3}; int length = sizeof(array)/sizeof(int); //InsertSort(array, length); //PrintArray(array, length); //BinaryInsert(array, length); //PrintArray(array, length); //ShellSort(array, length); //PrintArray(array, length); BubbleSort(array, length); PrintArray(array, length); //SimpleSelectSort(array, length); //PrintArray(array, length); //QuickSort(array, 0, 9); //PrintArray(array, length); //int array2[11] = {100, 7, 2, 8, 6, 9, 1, 5, 0, 4, 3}; //HeapSort(array2, 10); //PrintArray(array2, 11); //int arr2[10]; //MergeSort(array, arr2, 0, 9); //PrintArray(array, length); system("pause"); return 0; } // PrintArray void PrintArray(int *arr, int length) { for (int i=0;i<length;i++) { printf("%5d", arr[i]); } printf("\n"); } // 直接插入排序 // 稳定的排序,算法时间复杂度O(n2), 空间复杂度O(1) // 最少的比较次数,n-1次,记录不需要移动,本身就是排好序的 // 最多的比较次数,这里因为没有使用哨兵,所以和数据结构书上的不一样,最多比较次数(n-1)n/2 // 元素移动的最大次数:需要和临时变量相互移动两次,结果为(n-1)(n+4)/2 // 直接插入排序的比较次数,移动次数都比较多 void InsertSort(int * arr, int length) { for (int i=1; i < length; i++) { if (arr[i] < arr[i-1]) { int temp = arr[i]; int j = i - 1; do { arr[j+1] = arr[j]; j = j - 1; } while (j >= 0 && arr[j] > temp); arr[j+1] = temp; } } } // Binary Insert // 稳定的排序算法,时间复杂度O(n2),空间复杂度O(1) // 折半插入排序的元素移动的次数和直接插入排序一样,但是元素的比较次数减少,比较次数为 nlogn void BinaryInsert(int * arr, int length) { for (int i = 1; i < length; i++) { if (arr[i] < arr[i-1]) // 需要插入排序 { int left = 0; int right = i - 1; int temp = arr[i]; while(left <= right) { int mid = (left + right)/2; if (arr[mid] > temp) { right = mid -1; } else { left = mid + 1; } } int j = i - 1; do { arr[j+1] = arr[j]; j = j - 1; } while (j>=left); arr[left] = temp; } } } // 希尔排序(Shell sort) // Shell Sort 是不稳定的排序算法,算法复杂度O(n3/2) void ShellSort(int * arr, int length) { int gap = length; do { gap = gap/3 + 1; for (int i = 0 + gap; i < length; i++) { if (arr[i] < arr[i - gap]) // 需要插入 { int temp = arr[i]; int j = i - gap; do { arr[j+gap] = arr[j]; j = j - gap; } while (j>=0 && arr[j]>temp); arr[j + gap] = temp; } } } while (gap>1); } // Bubble Sort // 冒泡排序时稳定的,算法时间复杂度O(n2),空间复杂度O(1) // 冒泡排序最好情况下只需要进行n-1比较,不需要移动元素, 一趟比较无逆序,则退出排序 // 最差情况下需要比较 n(n-1)/2 次,并且也进行同数量级的元素移动 void BubbleSort(int * arr, int length) { for (int i = 0; i < length - 1; i++) { bool exchange = false; for (int j = length - 1; j>i; j--) { if (arr[j] < arr[j-1]) { exchange = true; int temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; } } if (exchange == false) { break; } } } // Simple Select Sort // 简单选择排序时不稳定的, 时间复杂度O(n2) // 元素的比较次数是固定的,与输入数组的情况无关,比较次数总是为 n(n-1)/2 // 最差情况下元素移动次数 3(n-1), <span style="font-size:18px;color:#ff0000;">元素的移动次数是所有的排序算法中最少的</span> void SimpleSelectSort(int * arr, int length) { for (int i = 0; i < length - 1; i++) { int index = i; // 记录最小的位置 for (int j = i + 1; j < length; j++) { if (arr[j] < arr[index]) { index = j; } } if (index != i) { int temp = arr[i]; arr[i] = arr[index]; arr[index] = temp; } } } // Quick Sort // 快排是不稳定的,算法时间复杂度 nlogn, 最差情况下退化为冒泡排序 // 就平均计算时间而言,快排是所有算法里效果最好的一个 void QuickSort(int * arr, int left, int right) { if(left < right) { int piovt = Partition(arr, left, right); QuickSort(arr,left, piovt -1); QuickSort(arr, piovt+1, right); } } // Partition int Partition(int * arr, int left, int right) { int pivot = arr[left]; while(left<right) { while(left < right && arr[right] >= pivot) --right; int temp = arr[right]; arr[right] = arr[left]; arr[left] = temp; while(left < right && arr[left] <= pivot) ++left; temp = arr[right]; arr[right] = arr[left]; arr[left] = temp; } return left; } // 堆排序 // 索引从1开始 // 堆排序的时间复杂度是 nlogn, 不稳定的 // 空间复杂度 O(1) void HeapSort(int * arr, int length) { // 调整堆,创建小根堆 for (int i = length/2; i >= 1; i--) { HeapAdjust(arr, i, length); } // 进行堆排序 for (int i = 1; i <= length; i++) { int temp = arr[1]; arr[1] = arr[length - i + 1]; arr[length - i + 1] = temp; HeapAdjust(arr, 1, length - i); } } void HeapAdjust(int * arr, int start, int length) { int temp = arr[start]; for(int i = start * 2; i <= length; i = i * 2) { if ( i < length && arr[i+1] < arr[i]) { i++; // 指向右边较小的数 } if (arr[i] < temp) { arr[start] = arr[i]; start = i; // 记录上一层节点,修改 start变量,记录上一层 } else { break; } } arr[start] = temp; } // 归并排序 // 归并排序时稳定的,时间复杂度 nlogn, 空间复杂度 O(n) // 归并排序的最好情况,最差情况,平均情况都是算法复杂度为O(n) void MergeSort(int * arr, int *arr2, int left, int right) { if (left < right) { int mid = (left + right)/2; MergeSort(arr, arr2, left, mid); MergeSort(arr, arr2, mid + 1, right); Merge(arr, arr2, left, mid, right); } } // Merge void Merge(int * arr, int *arr2, int left, int mid, int right) { for (int i = left; i <= right; i++) { arr2[i] = arr[i]; } int k = left; int i = left; int j = mid +1; while(i<=mid&&j<=right) { if (arr2[i] < arr2[j]) { arr[k++] = arr2[i++]; } else { arr[k++] = arr2[j++]; } } while(i<=mid) arr[k++] = arr2[i++]; while(j<=mid) arr[k++] = arr2[i++]; }