排序
来源:互联网 发布:潜韵耳机的官方淘宝店 编辑:程序博客网 时间:2024/04/29 10:49
排序
一、插入排序
1.直接插入排序
时间复杂度O(N^2)
思想:每次用无序区的第一个元素和有序区的元素从后往前比,找到合适的位置后,把有序区的元素依次后移,插入那个元素后使有序区再次有序
<span style="font-size:18px;">void InsertSort(int *a,int length){for (int i = 0; i < length-1; i++){int end = i;int tmp = a[end + 1];while (end>=0&&tmp < a[end]){a[end + 1] = a[end];end--;}a[end + 1] = tmp;}}</span>对于:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
第一次:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
第二次:0, 3,7, 5, 4, 8, 1, 9, 2, 6
第三次:0, 3, 5, 7, 4, 8, 1, 9, 2, 6
第四次:0, 3, 4, 5, 7, 8, 1, 9, 2, 6
...
2.希尔排序
时间复杂度在O(N^1.25)左右
由于直接插入排序在相对有序的情况下事效率比较高,最坏的情况就是相对逆序的情况,希尔排序是插入排序的优化,先进行预排序,设置一个gap,慢慢缩小gap的范围,达到其相对有序。
void ShellSort(int *a,int length){assert(a);int gap = length;while (gap > 1){gap = gap / 3 + 1;//慢慢缩小范围直到缩小到1for (int i = 0; i < length-gap; i++){int end = i;int tmp = a[end + gap];while (a[end]>tmp&&end>=0){a[end + gap] = a[end];end -= gap;}a[end + gap] = tmp;}}}
对于:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
第一次(gap=4):0, 6, 1, 5, 2, 7, 3, 9, 4, 8
第二次(gap=2) :0, 5,1, 6, 2, 7, 3, 8, 4, 9
第三次(gap=1):0, 1, 2, 3, 4, 5, 6, 7, 8, 9
二、选择排序
1.直接选择排序
时间复杂度:O(N^2)
思想:遍历选出这组数中最大的,和最后一个数做交换
void SelectSort(int *a,int length){int end = length - 1;for (; end > 0; end--){int MaxIndex = 0;for (int i = 0; i <= end; i++)//选出最大值的下标{if (a[MaxIndex] < a[i])MaxIndex = i;}swap(a[end], a[MaxIndex]);//交换到相对最后的位置}}
对于:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
第一次:0, 7, 3, 5, 4, 8, 1,6, 2,9
第二次:0, 7, 3, 5, 4,2, 1, 6, 8, 9
第三次:0,6, 3, 5, 4, 2, 1,7, 8, 9
第四次:0, 1, 3, 5, 4, 2,6, 7, 8, 9
……
-->优化
遍历时可以选出最大和最小的值的下标,将最小的放到相对头的位置,最大的放到相对尾的位置
void SelectSort(int *a, int length){assert(a);assert(length > 0);int end = length - 1;int start = 0;while (end > start){int iMax = start;int iMin = start;for (int i = start+1; i <= end; i++){if (a[i] >= a[iMax])iMax = i;if (a[i] < a[iMin])iMin = i;}if ((start != iMax)&&(end != iMin))//情况1{swap(a[start], a[iMin]);swap(a[end], a[iMax]);}if ((start == iMax)&&(end == iMin))//情况2{swap(a[iMax], a[iMin]);}if ((start == iMax)&&(end != iMin))//情况3{swap(a[iMax], a[end]);swap(a[iMin], a[start]);}if ((start != iMax) && (end == iMin))//情况4{swap(a[iMin], a[start]);swap(a[iMax], a[end]);}start++;end--;}}
对于:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
第一次:0, 7, 3, 5, 4, 8, 1, 6, 2, 9
第二次:0, 1, 3, 5, 4, 2, 7, 6, 8, 9
第三次:0, 1, 2, 5, 4, 3, 6, 7, 8, 9
第四次:0, 1, 2, 3, 4, 5, 6, 7, 8, 9
……
2.堆排序时间复杂度:O(N *logN)
利用堆的性质,先建一个大堆,使堆顶存放最大的元素,再依次用堆顶元素和相对最后的一个元素交换,从而把最大的排到后面,每交换一次,均需要把剩下的元素向下调整一次
void _AdjustDown(int *a, int size, int parent)//向下调整{int child = parent * 2 + 1;while (child < size){if (a[child] < a[child + 1]&&(child+1 < size)){child++;}if (a[child]>a[parent]){swap(a[child], a[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}}void HeapSort(int *a, int length){for (int i = (length-2)/2; i >=0 ; i--)//建堆{_AdjustDown(a, length, i);}for (int i = 0; i < length; i++)//排序{swap(a[0], a[length - 1 - i]);_AdjustDown(a, length-i-1, 0);}}
对于:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
建堆:9, 7, 8, 5, 6, 3, 1, 0, 2, 4
堆排序:第一次:8, 7, 4, 5, 6, 3, 1, 0, 2, 9
第二次:7, 6, 4, 5, 2, 3 , 1 ,0,8,9
……
三、交换排序
1.冒泡排序
时间复杂度:O(N^2)
void BubbleSort(int *a, int length){for (int i = 0; i < length; i++){for (int j = 0; j < length -1- i;j++){if (a[j]>a[j + 1])swap(a[j], a[j + 1]);}}}对于:0, 7, 3, 5, 4, 8, 1, 9, 2, 6
i=0: 0, 3, 5, 4, 7, 1, 8, 2, 6, 9
i=1: 0, 3, 4, 5, 1, 7, 2, 6, 8, 9
i=2: 0, 3, 4, 1, 5, 2, 6 ,7 ,8, 9
在它有序时它任然会循环,时间效率低,故设置一个值来判断它在循环的过程中是否发生交换,若没有发生循环,直接退出循环
-->优化
void BubbleSort(int *a, int length){bool exchange = false;for (int i = 0; i < length; i++){for (int j = 0; j < length - 1 - i; j++){if (a[j]>a[j + 1]){swap(a[j], a[j + 1]);exchange = true;}}if (exchange == false)//若没有发生交换说明已经有序break;}}
2.快速排序
int partition(int *a, int left, int right){int key = a[right];int begin = left;int end = right - 1;while (begin < end){while (a[begin] < key){++begin;}while (begin < end&&a[end]>key){--end;}if (begin < end){swap(a[begin], a[end]);}}if (a[begin]>a[right]){swap(a[begin], a[right]);return begin;}elsereturn right;}void QuickSort(int *a, int left,int right){assert(a);if (left < right){int div = partition(a, 0, right);QuickSort(a, 0, div - 1);QuickSort(a, div + 1, right);}}
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- Android SD卡路径问题
- Android studio -SVN 使用笔记
- 《深入理解mybatis原理(六)》 MyBatis缓存机制的设计与实现如何细粒度地控制你的MyBatis二级缓存
- hibernate 实现多表连接查询
- 【LeetCode】268. Missing Number
- 排序
- UITextField —— 键盘弹出视图上移
- JAVA类加载机制全解析
- Dubbo的helloworld maven版
- 傻瓜式Gson解析
- 个人笔记-递归构造树
- EventBus的使用和源码解析
- Atomikos 分布式数据源,spring,mybatis
- PAFA3设计开发指南