数据结构与算法——排序算法

1.排序算法的分类
排序算法:基本排序,多路归并排序
>基本排序:交换排序,选择排序,插入排序,合并排序
>>交换排序:冒泡排序,快速排序
>>选择排序:选择排序,堆排序
>>插入排序:插入排序,Shell排序

2.冒泡排序算法
(1)流程:
>1.对数组中的各数据,依次比较相邻的两个元素的大小;
>2.如果前面的数据大于后面的,则利用中间变量交换两个数据。经过一轮之后,便将最小的数据排好;
>3.再用同样的方法将剩下的数据排好

、、、
viod bubbleSort(int[] a){
int temp; //中间变量
for(int i=1; i<a.length; i++){
if(a[j] > a[j+1]){ //比较相邻数据大小
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
System.out.print("每步排序结果:");
for(int k=0; k<a.lenhth; k++){
System.out.print(a[k]+" ");
}
}
}
、、、

3.选择排序算法
(1)流程
>1.首先从原始数据种选择一个最小的数据,将其和第一个位置的数据交换;
>2.接着从 n-1 个数据中查找最小的数据,将其和第二个位置的数据交换;
>3.不断重复上述过程,直到最后两个数据交换完成。

、、、
viod selectSort(int[] a){
int temp; //中间变量
int index;

for(int i=1; i<a.length; i++){
    index = i;
    for(int j=i+1; j<a.length;j++){
        if(a[j] < a[j+1]){
            index = j;
        }
    }
    if(index != i){ //比较相邻数据大小
        temp = a[j];
        a[j] = a[index];
        a[index] = temp;
    }
    System.out.print("每步排序结果:");
    for(int k=0; k<a.lenhth; k++){
        System.out.print(a[k]+" ");   
    }
}

}
、、、

4.插入排序算法
(1)过程
>1.首先对数组的前两个数据进行从小到大的排序;
>2.接着讲第三个数据与排好序的两个数据比较,将第三个数据插入到合适的位置;
>3.然后将第4个数据插入到已排好的前三个数据中;
>4.不断重复上述过程,直到排好最后一个数据。

、、、
viod insertionSort(int[] a){
int i, j, t, h;

for(i=1; i<a.length; i++){
    t=a[i];
    j=i-1;
    while(j >= 0 && t<a[j]){
        a[j+1] = a[j];
        j--;
    }
    a[j+1]=t; 
    System.out.print("每步排序结果:");
    for(int k=0; k<a.lenhth; k++){
        System.out.print(a[k]+" ");   
    }
}

}
、、、

5.Shell排序算法
(1)流程:
>1.将有n个元素的数组分成你n/2(取整)个数字序列,第1个数据和第n/2+1个数据为一对...
>2.依次循环使每一个序列对排好顺序
>3.然后再变成n/4(取整)个序列,再次排序
>4.不断重复,随着序列的变少直到变成一个

、、、
viod shellSort(int[] a){
int i, j, h;
int r, temp;
int x=0;

for(r=a.length/2; r>=1;r/=2){
    for(i=r; i<a.length; i++){
        temp=a[i];
        j=i-r;
        while(j >= 0 && temp<a[j]){
            a[j+r]=a[j];
            j-=r;
        }
        a[j+r]=temp;
    }
    x++;
    System.out.print("第" +x+"步排序结果:");
    for(int k=0; k<a.lenhth; k++){
        System.out.print(a[k]+" ");   
    }
}

}
、、、

6.快速排序算法
(1)流程
>1.首先设定一个分界值,通过该值将数组分为左右两个部分;
>2.将大于等于分界值的数据集中到数组右边,小于的集中在数组左边;
>3.然后将左边和右边的数据独立快速排序;
>4.重复上述过程,直到完成,(递归)。

、、、
viod quickSort(int[] arr, int left, int right ){
int f, t;
int rtemp, ltemp;

ltemp=left;
rtemp=right;
f=arr[(left+right)/2];

while(ltemp<rtemp){
    while(arr[ltemp]<f){
        ++itemp;
    }
    while(arr[rtemp]>f){
        --rtemp;
    }
    if(ltemp<=rtemp){
        t=arr[ltemp];
        arr[ltemp]=arr[rtemp];
        arr[rtemp]=t;
        --rtemp;
        ++ltemp;
    }
}
if(ltemp==rtemp){
    ltemp++;
}
if(left<rtemp){
    quickSort(arr, left, ltemp-1);
}
if(ltemp<right){
    quickSort(arr, rtemp+1, right);
}

}
、、、

7.堆排序算法
堆排序的关键是首先构造堆结构。堆结构是一种树结构,准确的是一个完全二叉树,每个结点对应于原始数据的一个记录,并且每个结点应满足以下条件:
>如果按照从小到大的顺序,要求非叶结点的数据要大于或等于其左、右子结点的数据;
>如果按照从大到小的顺序,要求非叶结点的数据要小于或等于其左、右子结点的数据。

(1)流程(要求:从小到大输出)
>1.构造堆结构:把原始的无序数据按堆结构的定义进行调整。
>>首先:将原始数据放置到一个完全二叉树的各个结点中
>>然后:由完全二叉树的下层想上层逐层对父子结点的数据进行比较,使父结点数据大于子结点数据,到满足堆结构
>2.堆排序输出:将根结点与最后叶结点互换,并输出交换后的最后叶结点的值(即最大值)。

、、、
viod heapSort(int[] a, int n ){
int i, j, h, k;
int t;

for(i=n/2-1; i>=0; i--){
    while(2*i+1<n){
        j=2*i+1;
        if(j+1<n ){
            if(a[j])<a[j+1]{
                j++;                    
            }
        }
        if(a[i]<a[j]){
            t=a[i];
            a[i]=a[j];
            a[j]=t;
            i=j;
        }else{
            break;
        }
    }
}
//输出构成的堆
System.out.print("原数据构成的堆:");
for(h=0; h<n; h++){
    System.out.print(a[h]+" ");
}
System.out.print("\n ");

for(i=n-1; i>0; i--){
    t=a[0];
    a[0]=a[i];
    a[i]=t;
    k=0;
    while(2*k+1<i){
        j=2*k+1;
        if(j+1<i){
            if(a[j]<a[j+1]){
                j++;
            }
        }
        if(a[k]<a[j]){
            t=a[k];
            a[k]=a[j];
            a[j]=t;
            k=j;
        }else{
            break;
        }
    }
    System.out.print("第"+(n-i)+"步排序结果:");
    for(h=0; h<n; h++){
        System.out.print(a[h]+" ");
    }
    System.out.print("\n ");
}

}
、、、

8.合并排序算法
就是将多个有序数据表合并成一个有序数据表。如果是两个有序表的合并,则称为二路合并。
基本思路:首先将含有 n 个结点的带排序数据序列看成是由n个长度为1 的有序子表组成,将其依次进行两两合并并排序,得到长度为2的若干个有序子表;然后再对这些子表进行两两合并并排序,得到长度为4的若干个有序子表...

、、、
void mergeOne(int a[], int b[], int n, int len){
int i, j, s=0,e;
while(s+len<n){
e=s+2*len-1;
if(e>=n){ //
e=n-1;
}
//相邻有序段合并
k=s;
i=s;
j=s+len;
while(i<s+len && j<=e){
if(a[i]<=a[j]){
b[k++]=a[i++];
}else{
b[k++]=a[j++];
}
}
while(i<s+len){
b[k++]=a[i++];
}
while(j<=e){
b[k++]=a[j++];
}
s=e+1;
}
if(s<n){
for(; s<n; s++){
b[s]=a[s];
}
}
}

void mergeSort(int a[],int n ){
int h, count=0, len=1, f=0;
int[] p=new int[n];
while(len<n){
if(f==1){
mergeOne(p, a, n,len);
}else{
mergeOne(a, p, n, len);
}
len=len*2;
f=1-f;
count++;
System.out.print("第"+count+"步排序结果");
for(h=0; h<SIZE; h++){
System.out.print(a[h]+" ");
}
System.out.print("\n");
}
if(f==1){
for(h=0; h<n; h++){
a[h]=p[h];
}
}
}
、、、

9.排序算法的效率
数据量大小 n,各种排序算法的计算复杂度:
(1)冒泡排序:平均速度O(n^2),最坏情况下速度O(n^2);
(2)快速排序:平均速度O(nlogn),最坏情况下速度O(n^2);
(3)选择排序:平均速度O(n^2),最坏情况下速度O(n^2);
(4)堆排序:平均速度O(nlogn),最坏情况下速度O(nlogn);
(5)插入排序:平均速度O(n^2),最坏情况下速度O(n^2);
(6)Shell排序:平均速度O(n^(3/2)),最坏情况下速度O(n^2);
(7)合并排序:平均速度O(nlogn),最坏情况下速度O(nlogn).
其它概念:
稳定排序算法:依照相等的关键字维持记录的相对次序来进行排序。通俗地讲,对于两个有相等关键字的数据D1和D2,在待排序的数据中D1出现在D2之前,在排序过后的数据中D1也在D2之前,称为稳定排序算法。

猜你喜欢

转载自www.cnblogs.com/Cocoomg/p/9802357.html