数据结构经典排序

**数据结构经典排序
1,直接插入排序
2,希尔排序
3,选择排序
4,堆排序
5,冒泡排序
6,快速排序
7,归并排序

一 复杂度比较
在这里插入图片描述
在这里插入图片描述
二算法说明
(1)冒泡排序:

是相邻元素之间的比较和交换,两重循环O(n2);所以,如果两个相邻元素相等,是不会交换的。所以它是一种稳定的排序方法

(2)选择排序:

每个元素都与第一个元素相比,产生交换,两重循环O(n2);举个栗子,5 8 5 2 9,第一遍之后,2会与5交换,那么原序列中两个5的顺序就被破坏了。所以不是稳定的排序算法

(3)插入排序:

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。刚开始这个小序列只包含第一个元素,事件复杂度O(n2)。比较是从这个小序列的末尾开始的。想要插入的元素和小序列的最大者开始比起,如果比它大则直接插在其后面,否则一直往前找它该插入的位置。如果遇见了一个和插入元素相等的,则把插入元素放在这个相等元素的后面。所以相等元素间的顺序没有改变,是稳定的。

(4)快速排序
快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。

(5)归并排序
归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。

(6)希尔排序(shell)
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

(7)堆排序
我们知道堆的结构是节点i的孩子为2i和2i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n/2-1, n/2-2, …1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法
三 代码的编写

在这里插入代码片
```package java0324;

import java.util.Arrays;
import java.util.Stack;

public class jingdianpaixu {
    //1直接排序
    //思路:已排和待排区间
    public static void zhipai(int[] arr){
        int bound=1;
        for(;bound<arr.length;bound++){
            int v=arr[bound];
            int cur=bound-1;
            for(;cur>=0;cur--){
                if(arr[cur]>v){
                    arr[cur+1]=arr[cur];
                }else{
                    break;
                }

            }
            arr[cur+1]=v;
        }
    }
    //2希尔排序
      public static void shellSort(int[] arr){
        int gap=arr.length/2;
        while(gap>=1){
            _shellsort(arr,gap);
            gap=gap/2;
        }
      }
      public static void _shellsort(int[] arr,int gap){
        int bound=gap;
        for(;bound<arr.length;bound++){
            int v=arr[bound];
            int cur=bound-gap;
            for(;cur>=0;cur-=gap){
                if(arr[cur]>v){
                    arr[cur+gap]=arr[cur];
                }else {
                    break;
                }
            }
           arr[cur+gap]=v;
        }
      }
      //3选择排序----打擂台
    public static void selectsort(int[] arr){
        int bound=0;
        for(;bound<arr.length;bound++){
            for(int cur=bound+1;cur<arr.length;cur++){
                if(arr[cur]<arr[bound]){
                    swap(arr,cur,bound);
                }
            }
        }

    }
    public static void swap(int[] arr,int x,int y){
            int tmp=arr[x];
            arr[x]=arr[y];
            arr[y]=tmp;
    }
    //4,堆排序
      public static void duipai(int[] arr){
        //1,创建堆
            createHeap(arr);
            //2,交换元素
          int heapsize=arr.length;
          for(int i=0;i<arr.length;i++){
              swap(arr,0,heapsize-1);
              heapsize--;
              shutdown(arr,heapsize,0);
          }

            
      }
      public static void createHeap(int[] arr){
        for(int i=(arr.length-1-1)/2;i>=0;i--){
            shutdown(arr,arr.length,i);
          }
      }
      //5,冒泡排序
    public  static void bubblesort(int[] arr){
        for(int bound=0;bound<arr.length;bound++){
            for(int cur=arr.length-1;cur>bound;cur--){
                if(arr[cur-1]>arr[cur]){
                    swap(arr,cur-1,cur);
                }
            }
        }
    }
      public static void shutdown(int[] arr,int size,int index){
        int parent=index;
        int child=(parent*2)+1;
        while(child<size){
        if(child+1<size&&arr[child+1]>arr[child]){
            child=child+1;
        }
        if(arr[parent]<arr[child]){
            swap(arr,parent,child);
        }else{
            break;
        }
        parent=child;
        child=2*parent+1;}

      }
      //递归快速排序
    public static void quickSort(int[] arr){
        _quickSort(arr,0,arr.length-1);
    }
    public static void _quickSort(int[] arr,int left,int right){
        if(left>=right){
            return ;
        }
        //计算位置
        int index=zms(arr,left,right);
        _quickSort(arr,left,index-1);
        _quickSort(arr,index+1,right);

    }
    public static int zms(int[] arr,int left,int right){
        //选基准值
        int v=arr[right];
        int  a=left;
        int b=right;
        while(a<b){
            while(a<b&&arr[a]<=v){
                a++;
            }
            while(a<b&&arr[b]>=v){
                b--;
            }
            swap(arr,a,b);
        }
        swap(arr,a,right);
        return a;
    }
    //非递归快速排序
    public static void quicksortloop(int [] arr){
        Stack<Integer> stack =new Stack<>();
        stack.push(0);
        stack.push(arr.length-1);
        while(!stack.isEmpty()){
            int right=stack.pop();
            int left=stack.pop();
            if(left>=right){
               continue;
            }
            int index=zms(arr,left,right);
            //先进右边,后进左边
            stack.push(index+1);
            stack.push(right);
            stack.push(left);
            stack.push(index-1);
        }
    }
//   递归归并排序
    public static void mertSort(int[] arr){
        _mertsort(arr,0,arr.length);

    }
    public static void _mertsort(int[] arr,int left,int right){
        if(right-left<=1){
            return;
        }
        int mid=(left+right)/2;
        _mertsort(arr,left,mid);
        _mertsort(arr,mid,right);
        mert(arr,left,mid,right);
    }
    public static void mert(int [] arr,int left,int mid,int right){
        if(left>=right){
            return;
        }
    int[] zms=new int[right-left];
    int tmp=0;
    int cur1=left;
    int cur2=mid;
    while(cur1<mid&&cur2<right){
        if(arr[cur1]<arr[cur2]){
            zms[tmp]=arr[cur1];
            tmp++;
            cur1++;
        }else{
            zms[tmp]=arr[cur2];
            tmp++;
            cur2++;
        }
    }
    while(cur1<mid){
        zms[tmp]=arr[cur1];
        tmp++;
        cur1++;
    }
    while(cur2<right){
        zms[tmp]=arr[cur2];
        tmp++;
        cur2++;
    }
     for(int i=0;i<zms.length;i++){
         arr[left+i]=zms[i];

     }

    }
    //非递归排序
    public static void mergesortloop(int[] arr){
        int gap=1;
        for(;gap<arr.length;gap*=2){
            for(int i=0;i<arr.length;i+=gap*2){
                int left=i;
                int mid=i+gap;
                if(mid>arr.length){
                    mid=arr.length;
                }
                int right=i+2*gap;
                if(right>=arr.length){
                    right=arr.length;
                }
                mert(arr,left,mid,right);

            }
        }
    }

    public static void main(String[] args){
        int[] arr={9,5,2,7,3,6,8};
//        zhipai(arr);
//        shellSort(arr);
//        selectsort(arr);
//        duipai(arr);
//        bubblesort(arr);
//        quickSort(arr);
//        quicksortloop(arr);
//        mertSort(arr);
        mergesortloop(arr);

        System.out.println(Arrays.toString(arr));
    }
}

****
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值