数据结构-插入排序-希尔排序-快速排序

简介: 数据结构-插入排序-希尔排序-快速排序

正文


一、插入排序(Insertion Sort)


这个是直接插入排序基本思想:在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。过程:

1.jpg

平均时间复杂度:O(n^2)

代码的实现:


 public static void insert_sort(int array[],int lenth){
        int temp;
        for(int i=0;i<lenth-1;i++){
            for(int j=i+1;j>0;j--){
                if(array[j]<array[j-1]){
                    temp=array[j-1];
                    array[j-1]=array[j];
                    array[j]=temp;
                }else{         //不需要交换
                    break;
                }
            }
        }
    }


如果是二分插入排序,和这个相比,仅仅是我们在找到插入数据位置的方法是不同的,采用的是二分查找。


二、希尔排序(Shell Sort)


前言:数据序列1: 13-17-20-42-28 利用插入排序,13-17-20-28-42. Number of swap:1;数据序列2: 13-17-20-42-14 利用插入排序,13-14-17-20-42. Number of swap:3;如果数据序列基本有序,使用插入排序会更加高效。基本思想:在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。(也就是说步的大小为N的插入排序)过程:

2.jpg

时间复杂度:O(n^(1.3—2))

代码的基本实现:


public static void shell_sort(int array[],int lenth){
   int temp = 0;
   int incre = lenth;
   while(true){
       incre = incre/2;
       for(int k = 0;k<incre;k++){    //根据增量分为若干子序列
           for(int i=k+incre;i<lenth;i+=incre){
               for(int j=i;j>k;j-=incre){
                   if(array[j]<array[j-incre]){
                       temp = array[j-incre];
                       array[j-incre] = array[j];
                       array[j] = temp;
                   }else{
                       break;
                   }
               }
           }
       }
       if(incre == 1){
           break;
       }
   }
}


三、快速排序(Quicksort)


基本思想:(分治)先从数列中取出一个数作为key值;将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边;对左右两个小数列重复第二步,直至各区间只有1个数。辅助理解:挖坑填数

算法的基本过程:初始时 i = 0; j = 9; key=72由于已经将a[0]中的数保存到key中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。从j开始向前找一个比key小的数。当j=8,符合条件,a[0] = a[8] ; i++ ; 将a[8]挖出再填到上一个坑a[0]中。这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于key的数,当i=3,符合条件,a[8] = a[3] ; j-- ; 将a[3]挖出再填到上一个坑中。


数组:72 - 6 - 57 - 88 - 60 - 42 - 83 - 73 - 48 - 85 
0   1   2    3    4    5    6    7    8    9


此时 i = 3; j = 7; key=72再重复上面的步骤,先从后向前找,再从前向后找。从j开始向前找,当j=5,符合条件,将a[5]挖出填到上一个坑中,a[3] = a[5]; i++;从i开始向后找,当i=5时,由于i==j退出。此时,i = j = 5,而a[5]刚好又是上次挖的坑,因此将key填入a[5]。


数组:48 - 6 - 57 - 88 - 60 - 42 - 83 - 73 - 88 - 85 
0   1   2    3    4    5    6    7    8    9


可以看出a[5]前面的数字都小于它,a[5]后面的数字都大于它。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了。


数组:48 - 6 - 57 - 42 - 60 - 72 - 83 - 73 - 88 - 85 
0   1   2    3    4    5    6    7    8    9

平均时间复杂度:O(N*logN)

代码的实现:

public static void quickSort(int a[],int l,int r){
     if(l>=r)
       return;
     int i = l; int j = r; int key = a[l];//选择第一个数为key
     while(i<j){
         while(i<j && a[j]>=key)//从右向左找第一个小于key的值
             j--;
         if(i<j){
             a[i] = a[j];
             i++;
         }
         while(i<j && a[i]<key)//从左向右找第一个大于key的值
             i++;
         if(i<j){
             a[j] = a[i];
             j--;
         }
     }
     //i == j
     a[i] = key;
     quickSort(a, l, i-1);//递归调用
     quickSort(a, i+1, r);//递归调用
 }

key值的选取可以有多种形式,例如中间数或者随机数,分别会对算法的复杂度产生不同的影响。

相关文章
|
2月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
32 1
|
2月前
|
算法 搜索推荐
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
24 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
|
2月前
【初阶数据结构】打破递归束缚:掌握非递归版快速排序与归并排序
【初阶数据结构】打破递归束缚:掌握非递归版快速排序与归并排序
|
2月前
|
算法
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
|
4月前
|
存储 算法 搜索推荐
【初阶数据结构篇】冒泡排序和快速排序(中篇)
与直接插入排序法相比,比较次数一致,但冒泡排序的交换需要执行三次,而直接插入排序因为使用了tmp临时变量存储要插入的数据,只用执行一次,所以直接插入排序法效率明显更高。
36 1
|
5月前
|
搜索推荐
【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】
【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】
【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】
|
5月前
|
搜索推荐 测试技术
【数据结构常见七大排序(一)】—插入排序篇【直接插入排序】And【希尔排序】
【数据结构常见七大排序(一)】—插入排序篇【直接插入排序】And【希尔排序】
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
181 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
32 1
|
23天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
44 5