常用排序算法的C++实现

常用排序算法的C++实现

  1 #include<iostream>
  2 using namespace std;
  3 void swap(int &i,int &j)//实现i,j交换的函数
  4 {
  5     i=i^j;
  6     j=i^j;
  7     i=i^j;
  8 }
  9 void Display(const int *arr,int length)
 10 {
 11     if(arr==NULL || length<=0)
 12     {
 13         return ;
 14     }
 15     int i;
 16     for(i=0;i<length;i++)
 17     {
 18         cout<<arr[i]<<" ";
 19     }
 20     cout<<endl;
 21 }
 22 ////////////////////直接插入排序//////////////////
 23 void InsertSort(int *arr,int length)//直接插入排序
 24 {
 25     if(arr==NULL || length<=1)//如果大小为1也无需再排序
 26     {
 27         return ;
 28     }
 29     int i;
 30     for(i=1;i<length;i++)//从第二个值开始插
 31     {
 32         int temp=arr[i];//先保存待插入的值,因为移动会被覆盖
 33         int j;
 34         for(j=i-1;j>=0 && arr[j]>temp;j--)//一边比较一边移动
 35         {
 36             arr[j+1]=arr[j];
 37         }
 38         if(i!=j+1)//如果前面存在比a[i]小的数
 39         {
 40             arr[j+1]=temp;//在当前值的下一个位置插入
 41         }
 42     }
 43 }
 44 
 45 ///////////////////冒泡排序////////////////////////////
 46 void BubbleSort(int *arr,int length)//冒泡排序
 47 {
 48     if(arr==NULL || length<=1)
 49     {
 50         return ;
 51     }
 52     int i,j;
 53     bool change=true;//对冒泡排序的优化
 54     for(i=0;i<length-1 && change;i++)//i表示最多冒泡的次数
 55     {
 56         change=false;
 57         for(j=0;j<length-1-i;j++)
 58         {
 59             if(arr[j]>arr[j+1])//通过异或实现高效数据交换
 60             {
 61                 swap(arr[j],arr[j+1]);
 62                 change=true;
 63             }
 64         }
 65     }
 66 }
 67 
 68 /////////////////简单选择排序//////////////////////////
 69 void SelectSort(int *arr,int length)//简单选择排序
 70 {
 71     if(arr==NULL || length<=1)
 72     {
 73         return ;
 74     }
 75     int i,min;
 76     for(i=0;i<length-1;i++)
 77     {
 78         min=i;//每次假设第一个值为最小值
 79         int j;
 80         for(j=i+1;j<length;j++)
 81         {
 82             if(arr[min]>arr[j])
 83             {
 84                 min=j;//记下当前最小值的位置
 85             }
 86         }
 87         if(min!=i)
 88         {
 89             swap(arr[i],arr[min]);
 90         }
 91     }
 92 }
 93 ////////////////快速排序////////////////////////////////////
 94 int Partition(int *arr,int left,int right)//将数组一分为二,并寻找支点的位置
 95 {
 96     int x=arr[left];//每次将第一个值作为支点的值
 97     while(left<right)
 98     {
 99         while(arr[right]>=x && left<right)//从右向左扫描,注意是小于等于
100         {
101             right--;
102         }
103         if(left<right)
104         {
105             swap(arr[left],arr[right]);
106         }
107 
108         while(arr[left]<=x && left<right)//从左向右扫描,注意是小于等于
109         {
110             left++;
111         }
112         if(left<right)
113         {
114             swap(arr[left],arr[right]);
115         }
116     }
117     return left;//此时left等于right
118 }
119 
120 void QSort(int *arr,int left,int right)//快速排序,left=0,right=length-1
121 {
122     if(left<right)
123     {
124         int mid=Partition(arr,left,right);
125         QSort(arr,left,mid-1);
126         QSort(arr,mid+1,right);
127     }
128 }
129 
130 void QuickSort(int *arr,int length)
131 {
132     if(arr==NULL || length<=1)
133     {
134         return ;
135     }
136     QSort(arr,0,length-1);
137 }
138 
139 //////////////////////////归并排序/////////////////////////////////////
140 void Merge(int *arr,int first,int mid,int last,int *temp)//将arr[first...mid]与arr[mid+1...last]归并
141 {
142     int i,j;
143     int k=0;
144     for(i=first,j=mid+1;i<=mid && j<=last;)
145     {
146         if(arr[i]<=arr[j])//所以是稳定排序
147         {
148             temp[k++]=arr[i++];
149         }
150         else
151         {
152             temp[k++]=arr[j++];
153         }
154     }
155     while(i<=mid)
156     {
157         temp[k++]=arr[i++];
158     }
159     while(j<=last)
160     {
161         temp[k++]=arr[j++];
162     }
163     for(i=0;i<k;i++)//将合并后的数组temp[]还原到arr[]
164     {
165         arr[first+i]=temp[i];//是arr[low+i]不是arr[i]
166     }
167 }
168 void Msort(int *arr,int first,int last,int *temp)
169 {
170     if(first==last)
171     {
172         temp[first]=arr[first];
173     }
174     else if(first<last)
175     {
176         int mid=(first+last)/2;
177         Msort(arr,first,mid,temp);
178         Msort(arr,mid+1,last,temp);
179         Merge(arr,first,mid,last,temp);
180     }
181 }
182 void MergeSort(int *arr,int length)//归并排序
183 {
184     if(arr==NULL || length<=1)
185     {
186         return ;
187     }
188     int *temp=new int [length];
189     Msort(arr,0,length-1,temp);
190     delete []temp;
191 }
192 
193 //////////////////希尔排序////////////////////////
194 void ShellInsert(int *arr,int length,int d)
195 {
196     int i,j;
197     for(i=d;i<length;i++)
198     {
199         int temp=arr[i];
200         for(j=i-d;j>=0 && arr[j]>temp;j-=d)
201         {
202             arr[j+d]=arr[j];
203         }
204         if(j!=i-d)
205         {
206             arr[j+d]=temp;
207         }
208     }
209 }
210 
211 void ShellSort(int *arr,int length)//希尔排序
212 {
213     if(arr==NULL || length<=1)
214     {
215         return ;
216     }
217     int d=length/2;
218     while(d>=1)
219     {
220         ShellInsert(arr,length,d);
221         d/=2;
222     }
223 }
224 
225 ////////////////堆排序(大顶堆)//////////////////////////
226 ///////堆是一个完全二叉树,若结点索引从0开始,则i结点的左孩子为2*i+1,右为2*i+2
227 void HeapAdjustDown(int *arr,int length,int i)//对第i个值做向下调整,i=0,...,length-1
228 {
229     if(arr==NULL || length<=0 || i<0)
230     {
231         return ;
232     }
233     int temp=arr[i];
234     int j;//i相当于前驱,j相当于后继
235     for(j=2*i+1;j<length;)//即j<=length-1
236     {
237         if(j+1<length && arr[j]<arr[j+1])//如果存在右孩子,且右孩子值待遇
238         {
239             j++;//与右孩子交换
240         }
241         if(arr[j]<=temp)//如果左右孩子中的较大值小于该结点值,则说明无需向下调整了
242         {
243             break;
244         }
245         else//如果左右孩子中的较大值大于该结点值,则想到直接插入排序
246         {
247             arr[i]=arr[j];//孩子结点值中较大的上移动
248             i=j;//i用于追踪待插入点的位置
249             j=2*i+1;
250         }
251     }
252     if(arr[i]!=temp)//如果i的值发生了移动
253     {
254         arr[i]=temp;//将最初第i个节点值放入合适的位置
255     }
256 
257 }
258 void CreateHeap(int *arr,int length)//创建一个堆
259 {
260     if(arr==NULL || length<=0)
261     {
262         return ;
263     }
264     int i;
265     for(i=(length-2)/2;i>=0;i--)//最后一个元素的序号为length-1,故该结点的父结点为(length-2)/2
266     {
267         HeapAdjustDown(arr,length,i);//从倒数第二行开始倒着向下调整
268     }
269 }
270 void HeapDelete(int *arr,int len)//删堆顶元素,len表示当前表的长度
271 {
272     if(arr==NULL || len<=0 || len==1)//len=1,表示当堆中只有一个元素时,无需排序
273     {
274         return ;
275     }
276     else
277     {
278         swap(arr[0],arr[len-1]);
279         HeapAdjustDown(arr,len-1,0);//删除后,数组长度减1了
280     }
281 }
282 
283 void HeapSort(int *arr,int length)//堆排序
284 {
285     if(arr==NULL || length<=1)
286     {
287         return ;
288     }
289     CreateHeap(arr,length);//先创建一个堆0
290     int i;
291     for(i=0;i<=length-1;i++)//删除length-1次即可,因为最后一个元素就剩自己了
292     {
293         HeapDelete(arr,length-i);
294     }
295 }
296 int main()
297 {
298     int a[]={2,6,3,1,4,5,1,21,12,3};
299     Display(a,sizeof(a)/sizeof(int));//显示排序前的元素
300     //void (*pSort)(int*,int)=NULL;//定义一个函数指针,方法一
301     typedef void (*Fun)(int *,int);//Fun为函数指针类
302     Fun pSort=NULL;//定义函数指针,方法二,与上面等价
303 //    pSort=InsertSort;
304 //    pSort=BubbleSort;
305 //    pSort=SelectSort;
306 //    pSort=QuickSort;
307 //    pSort=ShellSort;
308     pSort=HeapSort;
309     if(pSort)
310     {
311         pSort(a,sizeof(a)/sizeof(int));//显示排序后的元素
312     }
313     Display(a,sizeof(a)/sizeof(int));
314     return 0;
315 }

本文转自:http://blog.csdn.net/jxh_123/article/details/22862251

原文地址:https://www.cnblogs.com/xymqx/p/4442283.html