Algorithms Lesson 1: Bubblesort
代码
for i = (n-1)to 1 for j = 0 to (i-1) if A[j] > A[j+1] swap (A[j], A[j+1])
复杂度分析
n 个元素, 比较次数有 (n-1) + (n-2) + ...... + 1 = n(n-1)/2,
O(n2)
Algorithms Lesson 2: Insertion Sort
代码
for i = 1 to n - 1 j = i while j > 0 and A[j] < A[j-1] swap (A[j], A[j-1]) j = j - 1
换个形式
void InsertSort(char array[],unsigned int n) { int i,j; int temp; for(i=1;i
算法复杂度
Algorithms Lesson 3: Merge Sort
代码
Algorithms Lesson 4:Selection sort
代码
// selection sort function module in C void selectionSort(int data[], int count) { int i, j, min, temp; for (i = 0; i < count - 1; i++) { /* find the minimum */ min = i; for (j = i+1; j < count; j++) { if (data[j] < data[min]) { min = j; } } /* swap data[i] and data[min] */ temp = data[i]; data[i] = data[min]; data[min] = temp; } }
复杂度分析
选择排序的交换操作介于0和(n − 1)次之间。选择排序的比较操作为n(n − 1) / 2次之间。选择排序的赋值操作介于0和3(n − 1)次之间。
比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。 交换次数O(n),最好情况是,已经有序,交换0次;最坏情况是,逆序,交换n-1次。 交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。
Algorithms Lesson 5:Merge sort
算法描述
代码
以下示例代码实现了归并操作。array[]是元素序列,其中从索引p开始到q位置,按照升序排列,同时,从(q+1)到r也已经按照升序排列,merge()函数将把这两个已经排序好的子序列合并成一个排序序列。结果放到array中。 static void merge(int array[], int low, int mid, int high) { int i, k; int *temp = (int *) malloc((high-low+1) * sizeof(int)); //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 int begin1 = low; int end1 = mid; int begin2 = mid + 1; int end2 = high; for (k = 0; begin1 <= end1 && begin2 <= end2; ++k) //比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 if(array[begin1]
算法复杂度
比较操作的次数介于(nlogn) / 2和nlogn − n + 1。 赋值操作的次数是(2nlogn)。 归并算法的空间复杂度为:Θ (n)
Algorithms Lesson 6:Quick sort
算法分析
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤为:
递回的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递回下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
代码
排序一个整数的阵列 void swap(int *a, int *b) { int t=*a; *a=*b; *b=t; } void quicksort(int arr[],int beg,int end) { if (end >= beg + 1) { int piv = arr[beg], k = beg + 1, r = end; while (k < r) { if (arr[k] < piv) k++; else swap(&arr[k], &arr[r--]); } if (arr[k] < piv){ swap(&arr[k],&arr[beg]); quicksort(arr, beg, k); quicksort(arr, r, end); }else { if (end - beg == 1) return; swap(&arr[--k],&arr[beg]); quicksort(arr, beg, k); quicksort(arr, r, end); } } }
Algorithms Lesson 7:Heapsort
算法分析
堆积树节点的访问
代码
#include
通常堆积树(heap)是通过一维数组来实现的。在起始阵列为 0 的情形中:
注意:不使用位置 0,否则左子树永远为 0[2]
堆积树的操作
在堆积树的数据结构中,堆积树中的最大值总是位于根节点。堆积树中定义以下几种操作:
归并操作的工作原理如下:
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数减去(n-1)次。平均来说插入排序算法复杂度为O(n2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。