基于顺序表的插入排序(常规插入排序,二分插入排序,希尔排序)
这三种的都是插入排序算法的时间复杂度基本相似,但由于希尔排序不同于其他排序方式的思想,所以其时间复杂度会有所不同。
常规插入排序:O(n2);
二分插入排序:O(n2);减少了找到插入位置的时间,但还是要一位位进行插入!
希尔排序:O(n1.25);
数据结构定义及其初始化函数:
typedef struct SqNode{
int data;
}SqNode;
typedef struct Node{
SqNode *head;
int length;
}SqList;
int Init_SqList(SqList &L)
{
L.head = new SqNode [N];
L.length = 1;
if (L.head)
return OK;
else
return ERROR;
}
常规插入排序:
void Insert_sort(SqList &L)
{
int ii,j;
for (ii = 2;ii < L.length;ii++)
{
if (L.head[ii - 1].data > L.head[ii].data) //优化:设置监视哨的方法进行优化!!!
{
L.head[0]= L.head[ii];
L.head[ii] = L.head[ii - 1];
for (j = ii - 1; L.head[j].data > L.head[0].data ;j--)
L.head[j + 1] = L.head[j];
L.head[j + 1] = L.head[0];
}
}
}
二分插入排序:
void Bin_Insert_sort(SqList &L)//二分插入排序
{
int left,mid,right;
int ii,j;
for (ii = 2;ii < L.length;ii++)
{
if (L.head[ii - 1].data > L.head[ii].data) // 优化
{
L.head[0] = L.head[ii];
//二分法查找插入位置
left = 1;
right = ii - 1;
while (left <= right) //注意这里的控制条件
{
mid = (left + right) / 2;
if (L.head[0].data < L.head[mid].data)
right = mid - 1;
else
left = mid + 1;
}
//
for (j = ii - 1;j >= right + 1;j --)
L.head[j + 1] = L.head[j];
L.head[j + 1] = L.head[0];
}
}
}
希尔排序:
void Hill_Insert_sort(SqList &L,int dk) //希尔排序
{
int ii,j;
for (ii = dk + 1;ii < L.length;ii++)
{
if (L.head[ii - dk].data > L.head[ii].data)
{
L.head[0] = L.head[ii];
L.head[ii] = L.head[ii - dk];
for (j = ii - dk;j > 0 && L.head[j].data > L.head[0].data;j-=dk) //因为j有可能减小为负数所以L.head[j].data <= L.head[0].data 有可能不会发生,所以要添加判断条件j < 0!!!
L.head[j + dk] = L.head[j];
L.head[j + dk] = L.head[0];//注意!!!
}
}
}
在实际调用时需要有外层循环来控制dk的值.
数据结构在考研中十分重要,所以我们应该熟练掌握相关代码及其思想.