知识点:
1.内部排序:把数据排序后放在内存里
2.外部排序:由于数据又是太多内存里存放不下,于是把数据放在内存外部
一.插入排序
基本思想:把数组第一个元素的位置设置为哨兵位,即把array[0]的位置设定为哨兵位,先比较array[1]和array[2]的大小,设较小的为2处的位置。然后把较小的先存到array[0]里,再定义一个变量控制数据的移动。先把较大(即1位置处)的和0位置处的数据进行比较,还是较大的话把它移动到之前哨兵位所在的位置,然后把哨兵位的数据移动到第一个数据处。依次类推。
函数实现:
<span style="font-size:18px;color:#330033;">void Insertsort(int array[],int n) //总体思想是利用哨兵位对数据进行插入或交换
{
for(int i=2;i<n;i++) //哨兵位暂时没有数据,所以比较的是1位置和2位置处的数据
{
if(array[i]<array[i-1])
{
array[0]=array[i]; //把较小的存放到0位置处,即哨兵位
for(j=i;array[0]<array[j-1];--j) //比较哨兵位和剩下的数据
{
array[j]=array[j-1]; //移动较大的数据到哨兵位的数据原先所在的位置处
}
array[j]=array[0]; //再把哨兵位的数据移动到较大位置处
}
}
} </span>
二.折半插入排序
基本思想:在插入排序的基础上加上了折半排序的思想。
函数实现:
<span style="font-size:18px;">void BInsertsort(Sqlist &L,int n)
{
for(int i=2;i<n;++i)
{
if(L[i]<L[i-1])
{
L[0]=L[i];
int low=1; //low是第一个元素的下标
int high=i-1;//high是最后一个元素的下标
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(L[mid]>L[0])
high=mid-1;
else
low=mid+1;
}
for(int j=i;i>low;--j)
{
L[j]=L[j-1];
}
L[low]=L[0];
}
}
}</span>
三.2-路插入排序(对数据的移动次数进行优化)
基本思想:类似于循环链表。用first和last分别指向头数组下标和尾数组下标,利用模来控制循环。
函数实现:
<span style="font-size:18px;">void TWayInsertsort(Sqlist &L,int n)
{
Sqlist T;
T[0]=L[0];
int first;
int last;
first=last=0;
for(int i=1;i<n;++i)
{
if(L[i]<L[first]) //和头比较
{
first=(first-1+n)%2;
T[first]=L[i];
}
else if(L[i]>=T[last]) //和尾比较
{
last++;
T[last]=L[i];
}
else //不大于头,又不小于尾
{
last++;
T[last]=T[last-1];
for(int j=last-1;L[i]<T[(j-1+n)%n];j=(j-1+n)%n)
{
T[j]=T[(j-1+n)%n];
T[j]=L[i];
}
}
for(i=0;i<n;++i)
{
L[i]=T[first];
first=(first+1)%n;
}
}
}</span>