#include
#include
#define MAXSIZE 100
typedef int KeyType;
typedef struct
{
KeyType key;
int data;
}RecType;
void InsertSort(RecType R[], int n)
{
int i, j;
RecType tmp;
for (i = 1; i < n; i++)
{
tmp = R[i];
j = i - 1;
while (j >= 0 && tmp.key < R[j].key)
{
R[j + 1] = R[j];
j--;
}
R[j+1] = tmp;
}
}
int main(void)
{
int i,n = 10;
RecType R[MAXSIZE];
KeyType a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for (i = 0; i < n; i++)
{
R[i].key = a[i];
}
printf("排序前");
for (i = 0; i < n; i++)
{
printf("%d ", R[i].key);
}
printf("\n");
InsertSort(R, n);
printf("排序后");
for (i = 0; i < n; i++)
{
printf("%d ", R[i].key);
}
printf("\n");
system("pause");
return 0;
}
算法的基本过程:
折半插入排序只是在寻找数的过程中用折半查找法,再移动数据过程中依然用的是传统的插入方法
对于有序的数据序列,采用折半查找法去判断在何处插入i位置上的数据,就大大减少了需要比较的次数。
1)计算 0 ~ i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;
2)在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2 1/4 1/8 …….快速的确定出第 i 个元素要插在什么地方;
3)确定位置之后,将整个序列后移,并将元素插入到相应位置。
代码块:
#include
#include
#define MAXSIZE 100
typedef int KeyType;
typedef struct
{
KeyType key;
int data;
}RecType;
void InsertSort(RecType R[], int n)
{
int i, j, low, high, mid;
RecType tmp;
for (i = 1; i < n; i++)
{
tmp = R[i];
low = 0;
high = i- 1;
while (low <= high)//只有low>high时才会跳出while循环
{
mid = (high + low) / 2;
if (tmp.key < R[mid].key) //要插入的数比R[mid]小,HIGH-1
{
high = mid - 1;
}
else//要插入的数比R[mid]大,LOW+1;
{
low = mid + 1;
}
}
for (j = i - 1; j >= high+1; j--)
{
R[j + 1] = R[j];
}
R[high + 1] = tmp;
}
}
int main(void)
{
int i, n = 10;
RecType R[MAXSIZE];
KeyType a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for (i = 0; i < n; i++)
{
R[i].key = a[i];
}
printf("排序前");
for (i = 0; i < n; i++)
{
printf("%d ", R[i].key);
}
printf("\n");
InsertSort(R, n);
printf("排序后");
for (i = 0; i < n; i++)
{
printf("%d ", R[i].key);
}
printf("\n");
system("pause");
return 0;
}
基本思想
设初始序列有n个元素,选定一个小于n大于或等于1的整数gap作为间隔,将全部元素分成gap个子序列,所有距离为gap的元素放在同一个子序列中,在每个子序列中分别采用直接插入算法进行排序;然后缩小间隔gap,如令gap=gap/2,重复上面的子序列划分和子序列排序动作;直到最后去gap=1,将所有的元素放到一个序列中为止。
代码块:
#include
#include
#define MAXSIZE 100
typedef int KeyType;
typedef struct
{
KeyType key;
int data;
}RecType;
void ShellSort(RecType R[],int n)
{
int i, j, gap, k;
RecType tmp;
gap = n / 2;
while (gap > 0)
{
for (i = gap; i < n; i++)
{
tmp = R[i];
j = i - gap;
while (j >= 0 && tmp.key < R[j].key)
{
R[j + gap] = R[j];
j = j - gap;
}
R[j + gap] = tmp;
j = j - gap;
}
gap = gap / 2;
}
}
int main(void)
{
int i, n = 11;
RecType R[MAXSIZE];
KeyType a[] = { 10,9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for (i = 0; i < n; i++)
{
R[i].key = a[i];
}
printf("排序前");
for (i = 0; i < n; i++)
{
printf("%d ", R[i].key);
}
printf("\n");
ShellSort(R, n);
printf("排序后");
for (i = 0; i < n; i++)
{
printf("%d ", R[i].key);
}
printf("\n");
system("pause");
return 0;
}
1、 直接插入排序:
① 思想:最基本的插入排序,将第i个插入到前i-1个中的适当位置。
② 时间复杂度:T(n) = O(n²)。
③ 空间复杂度:S(n) = O(1)。
④ 稳定性:稳定排序。循环条件while(r[0].key < r[j].key)保证的。
2、 折半插入排序:
① 思想:因为是已经确定了前部分是有序序列,所以在查找插入位置的时候可以用折半查找的方法进行查找,提高效率。
② 时间复杂度:比较时的时间减为O(n㏒n),但是移动元素的时间耗费未变,所以总是得时间复杂度还是O(n²)。
③ 空间复杂度:S(n) = O(1)。
④ 稳定性:稳定排序。
3、 希尔排序:
① 思想:又称缩小增量排序法。把待排序序列分成若干较小的子序列,然后逐个使用直接插入排序法排序,最后再对一个较为有序的序列进行一次排序,主要是为了减少移动的次数,提高效率。原理应该就是从无序到渐渐有序,要比直接从无序到有序移动的次数会少一些。
② 时间复杂度:O(n的1.5次方)
③ 空间复杂度:O(1)
④ 稳定性:不稳定排序。{2,4,1,2},2和1一组4和2一组,进行希尔排序,第一个2和最后一个2会发生位置上的变化。