常用排序算法的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
浙公网安备 33010602011771号