理想 == 离乡
慢点_慢点_再慢点__静点_静点_再静点

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 = 2i; / 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:

  • 每一趟排序使得一个元素归位,是全局有序
  • 是一个在顺序表中的完全二叉树
  • 大根堆(不小于孩子节点) 小根堆(不大于孩子节点)
posted on 2022-03-23 23:19  hwfre  阅读(75)  评论(0)    收藏  举报