排序算法(还需补充)

  1 /************
  2 十大排序算法
  3 ***********/
  4
  5 #include<iostream>
  6 #include<ctime>
  7 using namespace std;
  8
  9 typedef int T;
 10
 11 void swap(T &x,T &y)
 12 {
 13     T temp;
 14     temp=x;
 15     x=y;
 16     y=temp;
 17 }
 18 //1,冒泡  原地稳定 o(n^2)
 19 void bubble(T *a, int n)
 20 {
 21     for(int i=0;i<n-1;i++)
 22         for(int j=0;j<n-1-i;j++)
 23         {
 24             if(a[j]>a[j+1])
 25                 swap(a[j],a[j+1]);
 26         }
 27 }
 28
 29 void improvebubble(T *a, int n)
 30 {
 31     bool over=true;//作指示,若有一次没交换就结束
 32     for(int i=0;i<n-1&&over;i++)
 33     {
 34         over =false;
 35         for(int j=0;j<n-1-i;j++)
 36             if(a[j]>a[j+1])
 37             {
 38                 swap(a[j],a[j+1]);
 39                 over=true;
 40             }
 41     }
 42 }
 43 //2,插排 原地稳定 o(T)=1+2+3+..+n-1=o(n^2)
 44 void insert1(T *a,int n)
 45 {
 46     for(int i=1;i<n;i++)
 47     {
 48         T temp=a[i];
 49         int j;
 50         for(j=i-1;j>=0;j--)//和前面抽出来有序的比较
 51         {
 52             if(a[j]<=temp)
 53                 break;
 54             a[j+1]=a[j];
 55         }
 56         a[j]=temp;
 57     }
 58 }
 59
 60 int findpos(T *a,int n, T key)
 61 {
 62     int high=n-1,low=0;
 63     while(low<=high)//***这里要有等号,不然high=low(即排查到只剩一个数时)就不判断直接排在前面了
 64     {
 65         int mid=(high+low)/2;
 66         if(key>=a[mid]) //如果相等,定位到其后面,保证稳定排序
 67             low=mid+1;
 68         else if (key<a[mid])
 69             high=mid-1;
 70     }
 71
 72     return low;
 73 }
 74 void insert2(T *a,int n)
 75 {
 76     for(int i=1;i<n;i++)
 77     {
 78         T temp=a[i];
 79         int pos=findpos(a,i,temp);
 80         for(int j=i-1;j>=pos;j--)
 81         {
 82             a[j+1]=a[j];
 83         }
 84         a[pos]=temp;
 85         cout<<pos<<endl;
 86         for(int i=0;i<n;i++)
 87             cout<<a[i];
 88         cout<<endl;
 89     }
 90 }
 91
 92
 93 //3,选择排序 原地不稳定,一次选一个最小的, o(n^2)
 94 void select(T *a,int n)
 95 {
 96     for(int i=0;i<n-1;i++)
 97     {
 98         T min=a[i];
 99         int k=i;//重要一定要让k=i
100         for(int j=i+1;j<n;j++)
101         {
102             if(min>a[j])//找最小的
103             {
104                 min=a[j];
105                 k=j;
106             }
107         }
108         if(i!=k)//重要
109             swap(a[i],a[k]);//不稳定,比如a[i]不是最小的,它与最小发生交换,打乱了它自己的位置
110
111     }
112 }
113 //4.归并排序 非原地稳定 o(nlogn), 需要开辟o(n)的空间
114 //分治法,每次一分为二,最后将俩部分合并排序
115 void MergeSort(T *a,int f,int r,int mid)
116 {
117     int i=f,j=mid+1;
118     int m=mid,n=r;
119     int k=0;
120     T *temp=new T[r-f+1];//非原地排序,用来合并数组
121
122     while(i<=m && j<=n)
123     {
124         if(a[i]<=a[j])//这里等号可保证稳定
125             temp[k++]=a[i++];
126         else
127             temp[k++]=a[j++];
128     }
129     while(i<=m)
130         temp[k++]=a[i++];
131     while(j<=n)
132         temp[k++]=a[j++];
133     for(i=0;i<k;i++)//数组a局部有序
134         a[f+i]=temp[i];
135
136     delete [] temp;
137 }
138
139 void Merge(T *a,int f,int r)
140 {
141     if(f<r)
142     {
143         int mid=(f+r)/2;
144         Merge(a,f,mid);
145         Merge(a,mid+1,r);
146         MergeSort(a,f,r,mid);
147     }
148 }
149 void merge(T *a, int n)
150 {
151     Merge(a,0,n-1);
152 }
153
154 //5.快排,原地不稳定 o(nlogn)
155 void Quick(T *a,int f,int r)
156 {
157     if(f>=r)
158         return;
159     int i=f,j=r;
160     T temp=a[f];//第一个坑
161     while(i<j)
162     {
163         while(temp<=a[j] && i<j)//有可能越界
164             j--;
165         if(i<j)//如果俩者相遇,即跑到挖的坑那了
166             a[i++]=a[j];//后面的小的数填前面的坑
167         while(temp>a[i] && i<j)
168             i++;
169         if(i<j)
170             a[j--]=a[i];//用前面的大的数填后面的坑
171     }
172     a[i]=temp;//最后一坑
173     Quick(a,f,i);
174     Quick(a,i+1,r);
175 }
176 void quick(T*a,int n)
177 {
178     Quick(a,0,n-1);
179 }
180
181 //6.计数排序
182 //只能是整数(或字符)排序,而且要求分布比较均匀,非原地稳定
183 //好处是o(n)线性复杂度,方便序列去重操作
184 void count(T *a,int n)
185 {
186     T max=a[0],min=a[0];
187     int i;
188     for(i=0;i<n;i++)//找到序列最小值,以确定桶大小
189     {
190         if(max<a[i])
191             max=a[i];
192         if(min>a[i])
193             min=a[i];
194     }
195     int len=max-min+1;
196     T* C=new T[len];//记录每个数出现的次数
197     for(i=0;i<len;i++)
198         C[i]=0;
199     for(i=0;i<n;i++)
200         C[a[i]-min]+=1;
201     for(i=1;i<len;i++)
202         C[i]+=C[i-1];
203
204     T *R=new T[n];//
205     for(i=n-1;i>=0;i--)//倒着来取可保证稳定排序,后面的还排在后面
206     {
207         T temp=a[i];
208         int pos=C[temp-min];
209         R[pos-1]=temp;//注意这的减一.C统计的的是个数,R是从0开始存储的
210         C[temp-min]--;
211     }
212
213     for(i=0;i<n;i++)
214         a[i]=R[i];
215
216     delete [] C;
217     delete [] R;
218 }
219 //7,希尔排序 分组排序 原地不稳定
220 //数组基本有序的情况下更好
221 void shell1(T *a, int n)
222 {
223     for(int gap=n/2;gap>0;gap/=2) //log n
224         for(int i=gap;i<n;i++)//gap=1就是insertSort  o(n/gap)
225             for(int j=i-gap;j>=0 && a[j]>a[j+gap];j-=gap)
226                 swap(a[j+gap],a[j]);//或者可以先后推找到位置,最后填进去
227 }
228
229 void shell2(T *a,int n)//??不理解 o(nlogn)
230 {
231     int d=n;
232     while(d>1)
233     {
234         d=(d+1)/2;
235         for(int i=0;i<n-d;i++)
236             if(a[i+d]<a[i])
237                 swap(a[i+d],a[i]);
238     }
239 }
240
241
242 //8,堆排序 大根堆,向下调整 o(nlogn) 原地不稳定 适合处理大文件
243 void shiftdown(T *a,int n,int i)//
244 {
245     int t,flag=0;
246     while(2*i+1<n && flag==0)//以0为根节点,左右孩子是2i+1,2i+2
247     {
248         if(a[i]<a[2*i+1])
249             t=2*i+1;
250         else t=i;
251         if(2*i+2<n)//n是节点数,从1开始计的,而i是从0开始计的
252             if(a[t]<a[2*i+2])
253                 t=2*i+2;
254         if(t!=i)
255         {
256             swap(a[i],a[t]);
257             i=t;//继续往下调整
258         }
259         else flag=1;
260     }
261 }
262
263 void createMaxHeap(T *a,int n)//建立大根堆,o(n/2)
264 {
265     for(int i=n/2;i>=0;i--)//父节点向下调整
266         shiftdown(a,n,i);
267 }
268
269 void heapsort(T *a, int n)
270 {
271     createMaxHeap(a,n);
272     int k=n-1;
273     while(k>0)
274     {
275         swap(a[k],a[0]);
276         k--;
277         shiftdown(a,k,0);//o(logk)
278     }
279 }
280
281 int main()
282 {
283     const int n=15;
284     int a[n]={4,6,5,3,2,1,4,5,6,7,2,8,9,3,1};
285     shell2(a,n);
286     for(int i=0;i<n;i++)
287         cout<<a[i];
288     cout<<endl;
289     return 0;
290 }
时间: 2024-10-29 19:05:45

排序算法(还需补充)的相关文章

对八大排序算法的补充说明

1.算法时间复杂度的汇总 2.参考链接http://blog.csdn.net/hguisu/article/details/7776068

排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

数据结构杂谈(一)浅谈基本排序算法

0.基本概念 记录:待排序的项目 关键词:决定排序结果 稳定性:相同关键词的记录保持原来的相对次序 1.1插入排序(Insertion Sort) 算法思想 一种简单直观的排序算法,工作原理是通过构建有序序列:对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法描述 具体算法描述如下: 从第一个元素开始,该元素可以认为已经被排序 取出下一个元素,在已经排序的元素序列中从后向前扫描 如果该元素(已排序)大于新元素,将该元素移到下一位置 重复步骤3,直到找到已排序的元素小于或者等于

数据结构基础 排序算法(一) 概念篇

本辑将会对笔试面试最常涉及到的12种排序算法(包括插入排序.二分插入排序.希尔排序.选择排序.冒泡排序.鸡尾酒排序.快速排序.堆排序.归并排序.桶排序.计数排序和基数排序)进行详解.每一种算法都有基本介绍.算法原理分析.图解演示.算法代码.笔试面试重点分析.笔试面试题等板块. 一.插入排序 1)算法简介 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,通常

九大排序算法再总结

本文是 http://blog.csdn.net/xiazdong/article/details/7304239 的补充,当年看了<大话数据结构>总结的,但是现在看了<算法导论>,发现以前对排序的理解还不深入,所以打算对各个排序的思想再整理一遍. 本文首先介绍了基于比较模型的排序算法,即最坏复杂度都在Ω(nlgn)的排序算法,接着介绍了一些线性时间排序算法,这些排序算法虽然都在线性时间,但是都是在对输入数组有一定的约束的前提下才行. 这篇文章参看了<算法导论>第2.3

总结: Sort 排序算法

排序总结 面试经验 硅谷某前沿小Startup面试时,问到的一个题目就是写一个快速排序算法.进而面试官问到了各种算法的算法复杂度,进而又问了Merge Sort 与 QuickSort 的优劣. 对排序算法的全面理解,体现了计算机学生的功底. 现在来讲Merge Sort 与Quick Sort 是最流行的算法,以下我们来一步一步地分析: SORT分类 在计算机科学所使用的排序算法通常被分類為: 計算的時間複雜度(最差.平均.和最好表現),依據串列(list)的大小(n).一般而言,好的表現是O

排序算法--(二)

选择排序 直接选择排序: 选择排序,每一趟找到一个最小(大)值,每一趟遍历的数据减少一次. template <typename T> void SelectSort(T a[],int length) { T temp; for (int i=0;i<length;i++) { int k =i; for (int j=i+1;j<length;j++) { if (a[j]<a[k]) k=j; //这里只是对比它小的元素中最小的位置进行标记,每次相当于最多移动一次. }

排序算法汇总总结_Java实现

一.插入排序 直接插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间. 代码实现: public class Inseretion_Sort {     public static void main(Stri

排序算法 基于Javascript

写在前面 个人感觉:javascript对类似排序查找这样的功能已经有了很好的封装,以致于当我们想对数组排序的时候只需要调用arr.sort()方法,而查找数组元素也只需要调用indexOf()方法或lastIndexOf()方法,我们忽略了其内部的实现.而今,js能开发的项目越来越庞大,对性能和效率要求也越来越高,虽然众多的库和框架也可以帮我们应付这些问题,但小编觉得框架过眼云烟,把握程序开发的基础,才能在飞速的更新换代中应对自如.因此我们不妨也研究一下这些算法,其中的思路有助于我们自身的提高