1.插入排序:在第i趟排序中,把序列的第i+1个元素插入到前面i个元素组成的有序序列中,使得前i+1个元素变成一个大小为i+1,且有序的序列
2.选择排序:第i趟排序中从后面n-i+1个元素中选择一个最小的元素,将其置于这n-i+1个元素的前面。选择排序的元素之间的比较次数和元素的初始排列序列无关,都是要比较(n-1)n/2次
3.冒泡排序,这个比较简单,就不说了
4.谢尔排序(shell排序):首先确定一个元素的间隔数gap。将参加排序的元素按gap分割成若干个子序列(即把那些位置相隔为gap的元素看作一个子序列),然后对子序列里的元素按某种排序方式变成有序序列,然后减小gap值,一直到gap=0
5.堆排序:
1)调整堆的思想就是,先确定根节点的两个子树谁更大,然后把根节点往大子树移
2)建初始堆时,从最后一个分支结点(n为结点个数,则最后一个分支结点为n/2-1
)开始调整,一直调整成大顶堆
3)不稳定
4)代码如下:
//只能把输入的堆的根节点调整到一个合适的位置
void adjust(keytype k[ ],int i,int n)
{
int j;
keytype temp;
temp=k[i];
j=2*i+1;
while(j<n){
if(j+1<n && k[j]<k[j+1])
j++;
if(temp<k[j]) {
k[(j-1)/2]=k[j];
j=2*j+1;
}
else break;
}
k[(j-1)/2]=temp;
}
void heapSort(keytype k[ ],int n)
{
int i,
keytype temp;
for(i=n/2-1;i>=0;i– –)//从后面开始调整,是为了最后跑到这个堆的顶点时,确保两棵子树都是最大或者次大的(除堆的根节点外)
adjust(k,i,n);
for(i=n–1;i>=1;i– –){
temp=k[i];
k[i]=k[0];
k[0]=temp;
adjust(k,0,i);
}
}
注意,单纯的adjust函数只能把输入的堆的根节点调整到一个合适的位置,想要建立一个完整的堆还是得靠heapsort函数中的第一个for循环;完成了这个for循环后,就建成了一个真正的大顶堆;然后再依靠heapsort函数中的第二个for循环,才能完成堆排序;
另外就是,建堆时要从后往前建
6.归并:
1)稳定
7.快排:
1)不稳定
8.稳定性的总结:
所以就是,只有冒泡+插入+归并是稳定的;而选择+堆+快排+希尔是不稳定的
不太能记住,自己编了个口诀:冒插归稳,选堆快希不稳
9.容易混淆的是选择排序和插入排序,他们两者虽然都是让前面有序,但是选择排序的关键点是选择最小的排到前面去,插入排序则没有严格要选最小的
10.索引存储和顺序存储的区别是,索引是记录关键字值和记录的存储位置之间的对应关系,是个二元对