码迷,mamicode.com
首页 > 编程语言 > 详细

排序算法(还需补充)

时间:2015-05-13 23:10:09      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

  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 }

 

排序算法(还需补充)

标签:

原文地址:http://www.cnblogs.com/fkissx/p/4501998.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!