1. 交换两个数————位运算
static void swap(int *pa, int *pb)
{				
    *pa ^= *pb;
    *pb ^= *pa;
    *pa ^= *pb;
          
         return;
}
2. 简单选择排序
1. What:
-  每一趟在无序区选择一个最小的元素。 
-  把所选中的无序区中的元素放到有序区中的最终位置上。 
-  算法效率与初始数据的顺序性无关,因为当序列为正序时不会减少比较的次数。 
2.How:
static void selectSort(int a[], int n)
    {
        int i   = 0;
        int j   = 0;
        int Min = 0;
        for (i = 0; i < n-1; i++)       /* n 个数需要 n-1 的选择 */
        {
            Min = i;
            for (j = i+1; j < n; j++)   /* 从无序区中选择出最小的元素 */
            {
                if (a[Min] > a[j])
                {
                    Min = j;            /* 保存在无序区中的最小元素的下标 */
                }
            }
            if (Min != i)
            {
                swap(&a[Min], &a[i]);
            }
        }
        return;
    }
3.Why:
-  每一趟排序使得一个元素归位,有序区的元素一定小于(顺序)[大于(逆序)]无序区的元素,因此是全局有序的。
-  Min 用来保存无序区最小元素  的下标。
-  算法的效率与初始数据的状态无关(无论逆序还是正序,比较次数都不会减少)。
3. 堆排序
1. What:
-  是简单选择排序的改进 
-  初始建堆 ,a[0] 为哨兵,待排序元素存储在 a[1,n] 中
-  将 a[1, n] 调整为堆,交换 a[1] 和 a[k] (k = n n-1 ... 2)
2.How:
  /* 1. 完全二叉树调整为大根堆的算法 */
static void shiftHeap (int a[], int low, int high)
{
    int     i = low;
    int     j = 2*i;    /* a[j] 是 a[i] 的左孩子 */
    a[0] = a[i];        /* a[0] 临时备份数据*/
    while (j <= high)
    {
        /* j 指向较大的孩子 */
        if (j<high && a[j+1]>a[j]) /* 保证 j+1 有意义 */
        {
            j++;
        }
        if (a[j] > a[0])    /* 孩子结点大于父节点,需要调整 */
        {
            a[i] = a[j];
            i = j;
            j = 2*i;
        }
        else
        {
            break;
        }
    }
    a[i] = a[0];            /* 被筛选的节点放入最终的位置 */
}
static void heapSort (int a[], int n)
{
    int     i = 0;
    for (i=n>>1; i>=1; i--)     /* 初始建立大根堆 */
    {
        shiftHeap(a,i,n);
    }
    for (i=n; i>=2; i--)        /* 每一趟将无序区中一个最大的元素归位,需要 n-1 趟 */
    {
        swap(&a[1],&a[i]);
        shiftHeap(a,1,i-1);
    }
}
3.Why:
-  每一趟排序使得一个元素归位,是全局有序
-  是一个在顺序表中的完全二叉树 
-  大根堆(不小于孩子节点) 小根堆(不大于孩子节点)