八大排序算法
(一)选择排序法
原理:将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void SortList::SelectSort(int *list,int length) 2 { 3 int i,j,min; //i为有序区,j为无序区,min为无序区最小元素下标 4 for(i=0;i<length-1;i++) 5 { 6 min = i; 7 for(j=i;j<length;j++) 8 { 9 if(list[j]<list[min]) 10 min = j; 11 } 12 int t = list[i]; 13 list[i] = list[min]; 14 list[min] = t; 15 } 16 }
(二)冒泡排序法
原理:重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void SortList::BubbleSort(int *list,int length) 2 { 3 int i ,j; 4 for(i=0;i<length-1;i++) 5 { 6 for(j=0;j<length-i-1;j++) 7 { 8 if(list[j]>list[j+1]) 9 { 10 int t = list[j+1]; 11 list[j+1]=list[j]; 12 list[j]=t; 13 } 14 } 15 } 16 }
(三)插入排序法
原理:每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void SortList::InsertSort(int *list,int length) 2 { 3 int j,i;//分别为有序区和无序区 4 5 for(i=1;i<length;i++) 6 { 7 j=i-1; 8 if(list[i]<list[j]) 9 { 10 int temp = list[i]; 11 while(j>=0&&list[j]>temp) 12 { 13 list[j+1] = list[j]; 14 j--; 15 } 16 list[j+1] = temp; 17 } 18 } 19 }
(四)快速排序法
原理:快速排序的分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。然后再对这个数左右两段递归进行,以此达到整个数据变成有序序列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void SortList::QuickSort(int *list,int left,int right) 2 { 3 if(left<right) 4 { 5 int i = AdjustArray(list,left,right); 6 QuickSort(list,left,i-1); 7 QuickSort(list,i+1,right); 8 } 9 } 10 11 12 //快速排序的分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 13 int SortList::AdjustArray(int *list,int left,int right) 14 { 15 int base = list[left]; 16 while(left<right) 17 { 18 while(list[right]>base) 19 right--; 20 if(left<right) 21 { 22 list[left]=list[right]; 23 left++; 24 } 25 26 while(list[left]<base) 27 left++; 28 if(left<right) 29 { 30 list[right]=list[left]; 31 right--; 32 } 33 } 34 list[left] = base; 35 return left; 36 }
(五)希尔排序法
原理:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人
排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void SortList::ShellSort(int *list,int length) 2 { 3 int d,n,i,j; // 4 d = length/2; 5 while(d>=1) 6 { 7 for(n=0;n<d;n++) 8 { 9 for(i=n+d;i<length;i=i+d) 10 { 11 int temp ; 12 j = i-d; 13 if(list[j]>list[i]) 14 { 15 temp = list[i]; 16 while(list[j]>temp&&j>=0) 17 { 18 list[j+d]=list[j]; 19 j-=d; 20 } 21 list[j+d] = temp; 22 } 23 } 24 } 25 d=d/2; 26 } 27 }
(六)堆排序法
原理:利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //堆排序,堆是完全二叉树,设父节点下标为i,则其左子节点下标为i*2+1,右子节点下标为i*2+2 2 void SortList::HeapSort(int *list,int length) 3 { 4 //建堆,从最后一个根节点开始建堆,最后一个根节点下标为length/2-1 5 for(int i=length/2-1;i>=0;i--) 6 { 7 HeapAdjust(list,i,length); 8 } 9 10 for(int i=length-1;i>0;i--) 11 { 12 //先交换再重排 13 int temp = list[i]; 14 list[i] = list[0]; 15 list[0] = temp; 16 17 HeapAdjust(list,0,i); 18 } 19 } 20 21 //调整堆(大顶堆) 22 void SortList::HeapAdjust(int *list,int i,int length) 23 { 24 int left = i*2+1; 25 int right = i*2+2; 26 int maxindex = i; 27 28 if(left<length&&list[left]>list[maxindex]) 29 { 30 maxindex = left; 31 } 32 if(right<length&&list[right]>list[maxindex]) 33 { 34 maxindex = right; 35 } 36 37 if(maxindex!=i) 38 { 39 int temp = list[i]; 40 list[i] = list[maxindex]; 41 list[maxindex] = temp; 42 HeapAdjust(list,maxindex,length); 43 } 44 }