数据结构之排序

排序算法总结:
这里写图片描述

逐个分析排序算法:
1.插入类排序:像打扑克一样,第一张牌不用整理,从第二张开始将牌和之前的所有牌比较并插入到正确位置上。算法为:
★查找待插入元素的插入位置
★此位置之后的所有元素后移一位
★插入即可
(1)直接插入排序:
设一个监视哨r[0],用来存放待插记录,从第二个元素开始,和已经排好序的数列从后向前比较,直到找到大于待插记录停止,将比较过的数列整体后移,然后插入。
//此方法最坏时间复杂度为o(n*n),因为比较一趟,移动一趟;空间复杂度为o(1),因为只占用了一个监视哨;此方法是稳定的

public class test1 {
 public static void main(String[] args) {
  int i, j;
  int r[] = { 0, 0, 1, 9, 5, 15, 3, -5 };// 注意,第一个0是监视哨,占位置而已
  for (i = 2; i < r.length; i++) {//不是<=,因为0号位置没有用到
   r[0] = r[i];
   if (r[i] < r[i - 1]) {//当待排元素小于前一个元素时,才比较,否则不用比较。
    for (j = i - 1; r[j] > r[0]; j--) {//注意判断条件是大于
     r[j + 1] = r[j];//后移序列
     r[j] = r[0];//插入操作
    }
   } else {
    continue;
   }}
  for (i = 1; i < r.length; i++) {
   System.out.println(r[i]);
  }}}

(2)折半插入排序
同样设一个监视哨来存放当前待排元素,设置两个指针low和high,用中间值mid来和待排元素比较
//时间复杂度:移动加比较,仍为o(n*n),空间复杂度仍为O(1).且是稳定的。

public class test1 {
    public static void main(String[] args) {
        int i, j;
        int low, high, mid;
        int a[] = { 0, 0, -4, 25, 17, 1, -1, 5, 80 };
        for (i = 2; i < a.length; i++) {
            a[0] = a[i];
            if (a[i] < a[i - 1]) {
                low = 1;
                high = i - 1;
                while (low <= high) {
                    mid = (low + high) / 2;
                    if (a[mid] < a[0]) {
                        low = mid + 1;
                    } else {
                        high = mid - 1;
                    }}
                for (j = i - 1; j >= low; j--) {
                    a[j + 1] = a[j];
                    a[j] = a[0];
                }} else {
                continue;}}
        for (i = 1; i < a.length; i++) {
            System.out.print(a[i]);
            System.out.print("  ");
        }}}

(3)希尔排序:
2.交换类排序:对待排序的关键字两两进行比较,只要发现为逆序就进行交换,知道没有逆序的记录为止。
(1)冒泡排序:依次比较相邻两个关键字的大小,逆序则交换,最终每比较一趟,最大或者最小的数字沉到底。可以设置一个标志位flag,用来跟踪判断序列是否已完成排序。
时间复杂度:最优情况下,序列已有序,时间复杂度为o(n),最坏情况下,序列完全是乱的,则需要o(n*n)的时间复杂度。
是一种稳定的算法且空间复杂度为o(1).
//注意设置标志位a[0],用来实现交换过程。

public class test1 {
    public static void main(String[] args) {
        int i, j;
        int a[] = {0, 46, 25, 68, 33, 33, 19, 12, 80};
        System.out.println(a.length)
        for(j=1; j < a.length-1 ;j++) {//外层循环,循环次数不变
            for(i=1; i < a.length-j; i++) {//内层循环比较然后交换,循环次数依次减少
            if(a[i] > a[i+1]) {
                a[0] = a[i];
                a[i] = a[i+1];
                a[i+1] = a[0];
            }}}
        for(i=1; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }}}

(2)快速排序:几乎是最快的排序方法,采用分治的思想。
分治思想:将原问题分解为若干个规模更小但结构和原问题相似的子问题,递归的解这些子问题,然后将这些子问题的解组合为原问题的解
快排的思想:选择一个枢轴,设置high和low.两头同步开始交替比较,关键字小于枢轴的均移到枢轴之前,关键字大于枢轴的均移到枢轴之后。

public class test2 {
    static void quicksort(int n[], int low, int high) {
        if (low < high) {
            int dp = partition(n, low, high);
            quicksort(n, low, dp - 1);
            quicksort(n, dp + 1, high);}}//递归的过程
    static int partition(int n[], int low, int high) {//一趟比较的过程
        int pivot = n[low];
        while (low < high) {
            while (low < high && n[high] >= pivot)  high--;
            if (low < high)                      n[low++] = n[high];
            while (low < high && n[low] <= pivot)    low++;
            if (low < high)                        n[high--] = n[low];
        }
        n[low] = pivot;         return low;
    }
    public static void main(String[] str) {//主函数负责初始化和显示
    int n[] = { 0, -1, 53, 1, 36, 84, 19, 93, 113, 45, 23 }; 
            quicksort(n, 1, 10);
        for (int i = 1; i < 10; i++)
            System.out.print(n[i] + " ");}}

3.选择类排序:基本思想:k初始值为i=1的值,从所有剩下的记录中按顺序寻找小于关键字的记录,找到后将其位置赋给k,比较i和k的值是否相等,不相等则交换即可。
(1)简单选择:时间复杂度为o(n*n),空间复杂度为o(1),排序方式不稳定

public class test1 {
    static void sort(int a[]) {
        for (int i = 0; i <= a.length - 1; i++) {
            int k = i;
            for (int j = i + 1; j <= a.length - 1; j++) {
                if (a[j] < a[k])
                    k = j;}
            if (k != i) {
                int t = a[i];
                a[i] = a[k];
                a[k] = t;
            }}}
    public static void main(String[] args) {
        int a[] = { 1, -1, 3, 14, 0 };
        sort(a);
        for (int i = 0; i <= a.length - 1; i++) {
            System.out.println(a[i] + " ");
        }}}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值