算法基础--快排序,堆排序,归并排序

这是笔记;

快速排序的思想:先说一趟划分:一个数组a[0...(length-1)],把数组的第一个元素当作枢轴v(是vlaue,不是下标),将数组中所有比k小的元素都移动到k的左侧,将所有比v大的元素都移动到元素的右边。

        我们需要得到一个数组划分后,枢轴v现在的位置下标(这是下一步进行划分的边界);

        长度为n的数组,平均需要log(n)次划分。

代码实现:

 1 ///quick sort
 2     void quick_sort(int a[],int s,int t){//这是算法的开始,我们看到,输入s\t都是下标,下标和长度从一开始一定要区分开
 3         if(s<t){///那么这个算法什么时候结束呢?这是一个很常见的问题?----------》只要可划分数组a[]的长度大于1,就是说s<t,我们就对它进行划分。
 4             int k = Partition(a,s,t);///一趟划分,返回下一次划分的边界,这个k上的元素就排好了。我们可以利用了这个性质,做很多有意义的事情。,比如找到数组a中最小的k个数字;
 5             quick_sort(a,s,k-1);
 6             quick_sort(a,k+1,t);
 7         }
 8     }
 9
10
11     int Partition(int a[],int s,int e){///这就是划分算法,下面的while很经典。
12         int temp = a[s];///store the a[s] ,先创建一个临时变量来保存当前位置的元素值。
13         while(s<e){///只要多于一个元素,我们就运行划分算法
14             while(s<e && a[e]>=temp) e--;///从数组的后面向前开始找,先找第一个小于tmp的元素-->
15             a[s] = a[e];///-->将这个元素与a[s]交换
16             while(s<e && a[s]<=temp) s++;///从数组的前面向后开始找第一个大于tmp的元素
17             a[e] = a[s];///将这个元素和a[s]交换
18         }///while
19         a[s] = temp;///将tmp值放到最终的位置上,
20         return s;///返回找到元素的下标
21     }//Partition

堆排序:

堆排序思想:

  什么大根堆?完全二叉树中的每个节点元素  大于等于 它的孩子节点值 ;左右孩子节点间没有任何关系

  我们首先需要将一个数组a[]按照大根堆的标准建堆, 

     (1) 建好堆---》将数组a的第一个元素和最后一个元素调换,-----》再修复堆

       步骤(1) 我们需要迭代size(a)-1次,才能排好序。

这个思想很重要,因为 它能在一趟排好序的过程中,能在O(n)时间内建好堆; 但是建好堆后,对剩余的(n-i)的每个元素在log(n-i)时间内完成排序了;

代码:

 1 ///heap_sort algorithm
 2     void HeapSort(int a[],int n){///n is the index ,not the length
 3         for(int i = n/2;i>=0;i--){///build a big root heap
 4             Shift(a,i,n);
 5             for(int p = 0;p<=n;p++){
 6                 cout<<a[p]<<" ";
 7             }cout<<endl;
 8         }
 9
10         for(int i = n;i>0;i--){
11             int temp = a[0];
12             a[0] = a[i];
13             a[i] = temp;
14             Shift(a,0,i-1);///build the a[0..(i-1)] as a big-root heap
15         }
16     }
17     void Shift(int a[],int i,int m){///m is the index ,not the length
18         ///这个算法假设a[i+1...m]中的各个元素满足堆的定义,本算法调整a[i]使得序列a[i..m]中的元素满足堆的性质
19         ///要求不高,只是每次使大根堆的  元素数量多一个
20         ///调堆的过程,每次只在一个子树中操作,调换;
21         ///那么什么时候调换截止呢,就是说a[i]找到了要找的位置,就行了,我们这个函数的任务就结束了.
22         int temp = a[i];///暂存a[i]到temp
23         if(i==1){
24             cout<<"start"<<endl;
25         }
26         for(int j = 2*i+1;j<=m;j=2*i+1){///a[i]的左右孩子的下标分别是[2i],[2i+1]
27             if(j<m && a[j]<a[j+1]) j++;///若a[i]的右孩子存在,且关键字比较大,沿右孩子筛选
28                                         ///找当前a[i]最大的孩子节点和a[i]相比较即可,
29                                         ///大根堆的定义:只有节点和孩子节点的比较,没有孩子节点之间比较的意思
30             if(temp<a[j]){///这个孩子的key比较大
31                 a[i] = a[j];///将这个孩子节点放到双亲的位置
32                 i = j;///修改当前被调整的节点
33             }else{
34                 break;///调整完毕
35             }
36         }///for
37         a[i] = temp;///将最初被调整节点放到正确位置
38     }

  梳理一边数组建堆的过程:

 建堆也是不断调堆Shift的过程,shift(int a[],int i,int m)函数所作的工作就是将数组a[i...m]  (都是下标)。

归并排序:

归并排序思想:

代码:

 1     ///merger_sort algorithm
 2 void mergeArray(int * arrs, int * tempArr, int left, int middle, int right){
 3     int i = left, j = middle ;
 4     int m = middle + 1, n = right;
 5     int k = 0;
 6
 7     while(i <= j && m <= n){
 8         if(arrs[i] <= arrs[m])
 9             tempArr[k++] = arrs[i++];
10         else
11             tempArr[k++] = arrs[m++];
12     }
13     while(i <= j)
14         tempArr[k++] = arrs[i++];
15     while(m <= n)
16         tempArr[k++] = arrs[m++];
17
18     for(i=0; i < k; i++)
19         arrs[left + i] = tempArr[i];
20 }
21
22 void mergeSort(int * arrs, int * tempArr, int left, int right){
23     if(left < right){
24         int middle = (left + right)/2;
25         mergeSort(arrs, tempArr, left, middle);
26         mergeSort(arrs, tempArr, middle + 1, right);
27         mergeArray(arrs, tempArr, left, middle, right);
28     }
29 }
30
31 };
时间: 2024-10-08 10:17:25

算法基础--快排序,堆排序,归并排序的相关文章

C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序

以下列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序,然后是測试的样例.代码位置:http://download.csdn.net/detail/luozuolincool/8040027 排序类: public class Sortings { //插入排序 public void insertSort(int[] array) { int temp = 0; int index = 0; for (int i = 0; i <

算法基础之排序(2)--选择排序 改进

1 /********************************************************************************************************** 2 * Function : test 3 * Create Date : 2014/03/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性

算法基础之排序(1)--冒泡排序 改进

1 /********************************************************************************************************** 2 * Function : test 3 * Create Date : 2014/03/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性

算法基础:排序与查找

1.直接插入排序 1.1.基本思想: 在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的:如此反复循环,直到全部排好顺序. 1.2.实现思路: INSERTION_SORT(A) for i = 2 to n j = i-1 key = A[i] while j > 0 && A[j] > key A[j+1] = A[j] j-- A[j+1] = key 1.3.算法实现: pub

算法基础之排序

排序是生活中经常面对的问题,而根据排序过程中借助的主要操作,我们把内排序分为:插入排序.交换排序.选择排序和归并排序.这些都是比较成熟的排序算法,我们学习这些排序算法主要目的是通过学习它们来提高我们编写算法的能力,以便于解决更多复杂和灵活的应用性问题. 冒泡排序(Bubble Sort) 基本思想:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止. 算法实现: void bubbleSort(sqList *list) { int i, j; int flag = TRUE; f

在路上---学习篇(一)Python 数据结构和算法 (4) --希尔排序、归并排序

独白: 希尔排序是经过优化的插入排序算法,之前所学的排序在空间上都是使用列表本身.而归并排序是利用增加新的空间,来换取时间复杂度的减少.这俩者理念完全不一样,注定造成的所消耗的时间不同以及空间上的不同. 归并排序涉及到递归的使用,需要理解其中精髓才能更好了解归并排序,以及其他应用到递归的算法.理解其本质才能更好的应用. 希尔排序 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于195

[算法基础]快排、归并、堆排序比较

1.快速排序,上代码: def quickSort(arr): if len(arr) <= 1: return arr v = arr[0] high = [i for i in arr[1:] if i>=v] low = [i for i in arr[1:] if i<v] return quickSort(low) + [v] + quickSort(high) 分析一哈: 当不考虑最差情况(O(n^2))时,快排时间复杂度为O(nlogn):因为层数为O(logn)即调用栈的

算法基础——1.排序

排序算法 交换排序类:冒泡排序.快速排序 选择排序类:简单选择排序.堆排序 插入排序类:直接插入排序.希尔排序 冒泡排序 冒泡排序(Bubble Sort),排序的基本思想为两两比较小相邻数据的关键字,如果顺序为反则进行交换,直到没有反序的记录为止. 冒泡排序有多种变化,其三种不同实现的代码如下: //OS:Win | Terminal:Cmder | Editor:Atom | Language:c void Swap(int *a , int *b){ int temp = *a; *a =

数据结构算法基础-内部排序算法

1 arr = [1,23,12,9,8,8,9,1,1,8,] 2 def quickSortCore(arr,start,end): 3 if start < end: 4 index = partition(arr,start,end) 5 quickSortCore(arr,start,index-1) 6 quickSortCore(arr,index+1,end) 7 8 def partition(arr,start,end): 9 key = arr[start] 10 whil