前言:
该算法总结针对的是算法设计与分析课程所提到的算法,对于不同的人群可能获益有所不同,在叙述时会对一些较为简单的算法进行概性描述,目的是简单的告诉读者算法实现的基本原理,对一些较为复杂的算法则会付诸大量的笔墨,以求对算法的理解能够更加的透彻,这篇总结本人也会在博客上发布,以便长久性存储和便捷性阅读,其中描述错误或者不当的地方也请各位看官不吝赐教,菜鸡一个,谅解谅解。
排序种类:插入排序,选择排序,交换排序,归并排序
1.插入排序(Insertion-sort)
输入条件:待排序的数字预先存储在一个一维数组A[]中,共n个数
自然语言描述:从第二个数字元素开始直到最后一个数字结束,循环中的每一步将当前元素插进前面已经有序的数字序列当中,最终得到排序的数组
伪代码:
For i=2:n
Key=A[i];
Insert(key)//将key插入小标i前的已排序数列的合适位置
对于插入的方法有可以有不同的插入排序分类
折半插入:折半寻找元素插入点,插入后将后面的元素向后移动一位
直接插入:一边查找一边移动,直至找到插入点就停止
For(i=2:n)//直接插入
Key=A[i];
j=i-1;
while j>0&&A[j]>key
A[j+1]=A[j];//如果比key大就往前移动
j=j-1;//j指针向后移动
A[j+1]=key;//找到位置后key赋值给当前的数组元素,
这时A[j]>key为假。While循环结束
算法复杂度:O^2
联想:C++有专门进行数组排序的函数:sort 头文件<algorithm>
函数思想:快速排序
排序对象:list,vector,或者int型数组
用法:sort(begin,end,compare);
Sort(A,A+n);//compare缺省时默认升序排列从下标0开始的n个数组元素
Sort(A,A+n,compare)//按照compare中规定次序排列
Bool compare(int i,int j){returni<j;}//升序排列
Boolcompare(int I,int j){return i>j;}//降序排列
发现: string str(“abcs”);
String s(str.rbegin(),str.rend());//这时的s为str的逆序即”scba”
2.选择排序(Selection-sort)
输入条件:A[n]—n个元素的数组
算法思想描述:从头元素开始,不断选择后面元素中最小的元素放在已挑选排序的元素后面
这里进行的是顺序排序:
伪代码:
For(i=1:n-1)
j=i;
for(k=i+1:n)
if(A[k]<A[j])
j=k;
k++;
swap(a[i],A[j]);
算法复杂度:O^2;
3.冒泡排序(Bubble-sort)
输入条件:一个乱序的n个元素的数组
自然语言描述:依次比较相邻的两个数组,保证更大的数在后面,这个操作的结果是将最大的数字交换到了最后面,每次操作都从头元素开始,到终点结束,终点随每次操作逐渐向前移动一个元素。
伪代码:
For(i=0:n-1)
For(j=0:n-i-1)
If(A[j]>A[j+1])
Swap(A[j],A[j+1];
为了避免在已经排序提前完成的情况下,进行多余的操作,可进行改进如下:
Exchange=true;
For(i=0:n-1)
If(exchange==false) break;
Exchange=true;
For(j=0:n-i-1)
If(A[j]>[A[j+1]]
Swap(A[j],A[j+1]);
Exchange=true;
4.分治排序(Mergesort)
输入条件:一个乱序的n个元素的数组A[]
思想描述:使用递归方法对数组不断对半分割,分割到最后(即一个数时便不能再分割),这时开始递归回溯进行合并,合并时借助另一个数组B[],将合并后的一段元素存储在其中相应的位置,最后复制回来,逐渐回溯到整个数组,得到排序的数组
伪代码:
Mergesort(A,i,j)
K=(i+j)/2;
Mergesort(A,i,k)
Mergesort(A,k+1,j)
l=i;h=k+1;t=i;
While(l<=k&&h<=j)
If(A[l]<A[h])B[t]=A[l];l++;t++;
Else B[t]=A[h];h++;t++;
If(l<=k)//如果前一半的还有剩余元素
For(v=l:k)
B[t]=A[v];t++;
If(h<=j)//如果后半还有剩余元素
For(v=h:j)
B[t]=A[v];t++;
For(v=i:j)//将排序后的这一段元素复制到原数组中
A[v]=B[v];
5.快速排序(Quicksort)----很经典也很常用的排序算法
输入条件:一个乱序的n个元素的数组
思想描述:借鉴分治的原理,对每一段元素选取最后一个元素作为中间数,经过不断的交换,最终保证该数前面的元素更小,后面的元素更大,不断深入进行直到最底层,即只剩余一个数,这时便得到了排序后的数组
伪代码:
Quicksort(A,p,r)
If(p<r)
q=Partition(A,p,r)
Quicksort(A,p,q-1)
Quicksort(A,q+1,r)
Partition(A,p,r)
x=A[r];
i=p-1;
for(j=p;j<r;j++)
if(A[j]<=x)
i++;
swap(A[j],A[i]);
swap(A[r],A[i+1];
return i+1;
6.堆排序(Heap_sort)---也很重要
输入条件:一个乱序的n个元素的数组,按照数组顺序排列成一个二叉树
算法思想:
调整堆(Max_Heapify—核心操作):从某一个结点开始 ,比较该结点,左结点,右结点,将该结点与最大值的结点交换,交换后可能会破环每一个节点比他的子节点更大的性质,所以要从刚才找到的结点处往下进行,循环此操作
Max_Heapify(A,i)
l=left(i);r=Right(i);//记录左右结点的数组下标一般:l=i*2;r=i*2+1
if(l<Hsize(A)&&A[l]>A[i])
max=l;
else
max=i;
if(r<Hsize(A)&&A[r]>A[max])
max=r;
if(max!=i)
swap(A[max],A[i])
Max_Heapify(A,max);
中间方法:Build_max_heapify(A)
Hsize=len(A);
For(i=len(A)/2:1)
Max_heapify(A,i);
堆排序思想:先进行一次堆调整,使其满足堆性质,再从尾部到第二个元素每次执行:当前元素与堆顶元素交换,大小减小,从顶部进行堆调整
Heap_sort(A)
Bulid_max_heapify();
For(i=len(A) to 2
Swap(A[1],A[i])
Hsize=Hsize-1;
Max_heapify(A,1);
剩余排序方法:统计排序(Counting Sort),线性排序(radix sort),桶排序(Bucket Sort)相对简单,就不再详细说明了