* 不变性:
* 在很多算法中,有些条件在算法执行时是不变的,这些条件被称为不变性,
* */
//冒泡排序
public class MaoPao {
public static void main(String[] args) {
int [] a={3,5,2,6,4,34,8,7,5,4,23};
int[] s=maopaoSotr(a);
for(int i=0;i<s.length;i++){
System.out.print(s[i]+"--");
}
}
public static int[] maopaoSotr(int [] a){
int out,in;
for(out=a.length-1;out>1;out--){
for(in=0;in<out;in++){
if(a[in]>a[in+1]){
int t=a[in];
a[in]=a[in+1];
a[in+1]=t;
}
}
}
return a;
}
}
//插入排序
/*思想:
* 假设左边部分已经排序好了,从某个位置开始无序(比如4),将4赋予一个临时变量,然后再和前面的数据比较,
* 大多数情况下,插入算法任然需要O(N^2)的时间,比冒泡快一倍,比选择排序也要快一点。经常被用到复杂排序的最后阶段,如快排
*
* */
public class Insert_sort {
public static void main(String[] args) {
int [] a={3,5,2,6,4,34,8,7,5,4,23};
int[] s=insertSort(a);
for(int i=0;i<s.length;i++){
System.out.print(s[i]+"--");
}
}
public static int[] insertSort(int[] a){
int in,out;
/*
* 外层的for循环中,out变量从1开始,向右移动,他标记了未排序部分的最左端的数据
* 而在内层while循环中,in变量从out变量开始,向左移动,直到t变量小于in所指的数组数据项,或是他已经不能再往左移动为止。
* while循环的每一次都想右移动了一个排序的数据项
* 在每次结束时,在将t位置的项插入后,比out变量下标号小的数据项都是局部有序的
比较次数,1+2+3+...+(N-1) = Nx(N-1)/2,而因为每一次排序发现插入点之前,平均只有全体数据项的一半真的进行了比较,所以是N*(N-1)/2 /2<br>
复制的次数大致等于比较的次数。复制和交换的时间耗费不同。相对于随机数据,这个算法比冒泡快一倍,比选择排序略快。<br>
对于已经有序或基本有序的数据来说,插入排序要好得多。对于逆序排列的数据,每次比较和移动都会执行,所以插入排序不比冒泡排序快。
* */
for(out=1;out<a.length;out++){
int t=a[out];
in=out;
while(in>0 && a[in-1]>=t){
a[in]=a[in-1];
--in;
}
a[in]=t;
}
return a;
}
}
//选择排序
public class Select_sort {
public static void main(String[] args) {
int [] a={3,5,2,6,4,34,8,7,5,1,23};
int[] s=seletcSort(a);
for(int i=0;i<s.length;i++){
System.out.print(s[i]+"--");
}
}
public static int[] seletcSort(int[] a){
int out,in,min;
for(out=0;out<a.length-1;out++){
min=out;
//System.out.print("--"+min+"-"+a[min]);
//int [] a={3,5,2,6,4,34,8,7,5,1,23};
for(in=out+1;in<a.length;in++){
if(a[in]<a[min]){
min=in;
}
}
int t=a[out];
a[out]=a[min];
a[min]=t;
}
return a;
}
}
//归并排序
/*
* 归并时间复杂度只要O(NlogN),而冒泡排序,选择排序,插入排序都要用O(N*N)
归并排序的思想是:将一个数组分成两半,然后分别排序,然后将数组的两半合并,合并的时候需要比较大小
(合并的时候还要考虑两小数组还有没有数据,即有可能一边有,另一边没有)。
至于如何排序1/2半的数组,当然是再分成两个1/4数组,再排序。。。直到分割的小数组只有1个数据项,不用排序了。这是用到递归的思想
归并排序的缺点,需要在存储器中有另一个大小等于被排序的数据项数目的空间,用来复制分割出来的小数组。
归并算法的效率由来:需要复制log2/N层(分子数组),每一个层都是N个数据,所以是NxlogN.
* */
public class Merg_sort {
public static void main(String[] args) {
int [] a={3,5,2,6,4,34,8,7,5,4,23};
int[] s=mergSort(a);
for(int i=0;i<s.length;i++){
System.out.print(s[i]+"--");
}
}
public static int[] mergSort(int[] a){
int[] temp=new int[a.length];
reMergeSort(a,temp,0,a.length-1);
return a;
}
private static void reMergeSort(int[] a, int[] temp, int low, int hight) {
if(low==hight){
return;
} else{
int mid=(low+hight)/2;
reMergeSort(a,temp,low,mid);
reMergeSort(a,temp,mid+1,hight);
merge(a,temp,low,mid+1,hight);
}
}
private static void merge(int[] a, int[] temp, int low, int mid, int hight) {
int j=0 ;
int low1=low;
int mid1=mid-1;
int n=hight-low+1;
while(low<=mid1 && mid<=hight){
if(a[low]<a[mid]){
temp[j++]=a[low++];
}else{temp[j++]=a[mid++];}
}
while(low<=mid1){
temp[j++]=a[low++];
}
while(mid<=hight){
temp[j++]=a[mid++];
}
for(j=0;j<n;j++){
a[low1+j]=temp[j];
}
}
}
//希尔排序
/*
* 希尔排序基于插入排序,但增加了一个新的特性,大大地提高了插入排序的执行效率。(希尔是个人名。。。)
改进的地方:插入算法中,如果一个数据比较小而居于最右边,那么它需要一个一个地移动所有中间的数据项,效率比较低。
希尔排序通过加入插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项能大跨度地移动。
当这些数据项排过一趟序后,减小数据项的间隔。再进行排序,依次进行下去。间隔被称为增量,用h表示.<br>
进行过几次增量排序后,所有的元素离它再最终有序序列中的位置相差不大,数组达到"基本有序",这时再来插入排序,移动量非常小
当h值很大的时候,数据项每一趟排序需要移动元素的个数很少,但数据项移动的距离很长,
这是非常有效率的。当h减少时,每一趟排序需要移动的元素的个数增多,但是此时数据项已经接近于它们排序后最终的位置,
这对于插入排序可以更有效率。
其中,h = h x 3 +1, h = (h -1) / 3,是经验值。
*
*
* */
public class Sell_sort {
public static void main(String[] args) {
int [] aa={3,5,2,6,4,34,8,7,5,4,23};
int[] a=sellSort(aa);
for(int t=0;t<a.length;t++){
System.out.print(a[t]+"--");
}
}
void shellsort1(int a[], int n)
{
int i, j, gap;
for (gap = n / 2; gap > 0; gap /= 2) //步长
for (i = 0; i < gap; i++) //直接插入排序
{
for (j = i + gap; j < n; j += gap)
if (a[j] < a[j - gap])
{
int temp = a[j];
int k = j - gap;
while (k >= 0 && a[k] > temp)
{
a[k + gap] = a[k];
k -= gap;
}
a[k + gap] = temp;
}
}
}
public static int[] sellSort(int [] a){
int in,out,t;
int h=1;
for(h=a.length/2;h>0;h/=2)
for(out=0;out<h;out++){
for(in=out+h;in<a.length;in+=h)
if(a[in]<a[in-h]){
int temp=a[in];
int k=in-h;
while(k>=0 && a[k]>temp){
a[k+h]=a[k];
k-=h;
}
a[k+h]=temp;
}
}
return a;
}
static void shellsort3(int a[])
{
int i, j, h;
int n=a.length;
for (h = n / 2; h > 0; h /= 2) {
for (i = h; i < n; i++) {
for (j = i - h; j >= 0 && a[j] > a[j + h]; j -= h)
{
int t=a[j];
a[j]=a[j+h];
a[j+h]=t;
}
}
}
for(int t=0;t<a.length;t++){
System.out.print(a[t]+"--");
}
}
}