【数据结构】:排序--交换排序
2017-02-28 22:48
148 查看
交换排序
1、基本思想思想的核心是“交换”,是指借助序列中元素之间的相互交换进行排序的方法。
2、种类
冒泡排序
快速排序
冒泡排序
1、基本思想抓住两个点:趟数和次数
对于冒泡排序,一个元素要经过多少趟才能冒出头,其他的元素要经过同样的形式多少次。
2、代码实现
基本实现
void BubbleSort(int*a, size_t sz) { int i = 0; int j = 0; int temp = 0; int sz = sizeof(arr)/sizeof(arr[0]); for(i = 0; i<sz-1; i++) //表示要排多少趟 { for(j = 0; j<sz-i-1; j++) //表示每一趟要比较多少次 { if(arr[j] < arr[j+1]) { flag = 1; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }
优化实现
1)优化1:加标志位
说明:我们来想一种极端的情况:如果这个序列原本就是排好序的,那么也要经过N^2/2次,因为我们不知道它是排好序的,所以此处的优化就是加一个标志位,在内循环中,如果发现已经排好序了,就可以跳出了。
代码实现:
void BubbleSort(int*a, size_t sz) { int i = 0; int j = 0; int temp = 0; int flag = 1; int sz = sizeof(arr)/sizeof(arr[0]); for(i = 0; i<sz-1; i++) //表示要排多少趟 { flag = 0; //加标记进行优化 for(j = 0; j<sz-i-1; j++) //表示每一趟要比较多少次 { if(arr[j] < arr[j+1]) { flag = 1; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } if(flag == 0) break; }
2)优化2:
说明:我们再想象一种极端情况:array长度为n,但是只有0,1元素未排序,那么依照上一种优化算法我们依然要遍历2*n次。原因在于我们内层循环长度的设定依据是,i次排序array的后i-1个元素是排序好的,但实际上i次排序的循环长度取决于i-1次排序时最后的交换位置,例如i-1次排序的最后交换位置是index,则表明index之后的元素都已经排序完毕,我们只需要记录这个Index就得到了下次(i次)的循环长度。
代码实现:
void BubbleSort(int*a, size_t sz) { int i = 0; int j = 0; int temp = 0; int flag = 1; int index = 0; int mark = sz-1;//用于记录前i-1个元素排好序后的下标 int sz = sizeof(arr)/sizeof(arr[0]); for(i = 0; i<sz-1; i++) //表示要排多少趟 { flag = 0; //加标记进行优化 for(j = 0; j<mark; j++) //表示每一趟要比较多少次 { if(arr[j] < arr[j+1]) { flag = 1; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; index = j; } } if(flag == 0) break; mark = index; } }
3、时间复杂度
最好的情况是:O(N)
最坏的情况:O(N^2)
快速排序
1、基本思想它其实是对冒泡排序的一种改进,首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。然后两部分的数据再分别进行快速排序,可以用递归进行实现。
2、快排如何实现
划分的三种方法
1)左右指针法
*说明:
*代码实现(后附)
2)挖坑法
*说明:
*代码实现:(后附)
3)前后指针法
*说明:
*代码实现:(后附)
- 优化的两种方法 - 1)三数取中法 *说明: 我们如果取得数是接近这组数中的中间值的话,那么进行排序的时候效率就大大的上去了 *代码实现 :
int GetMidIndex(int* a,int left,int right) { int mid = left+ ((right-left)>>1); if(a[left] < a[mid]) { if(a[right] > a[mid]) return mid; else if(a[left] < a[right]) return right; return left; } else { if(a[left]< a[right]) return left; else if(a[mid] < a[right]) return right; else return mid; } }
- 2)小区间优化 *说明: 我们在进行递归实现其他部分的时候,当数据比较小的时候,我们可以使用直接插入法来进行排序,这时就免去了递归时压栈等等的一些开销。 *代码实现:
void QuickSort(int* a,int left, int right) { if(right-left < 20) { Insert(a+left,a+right-1); } else{ if(left < right) { int div = PartSort(a,left,right); QuickSort(a,left,div-1); QuickSort(a,div+1,right); } } }
3非递归实现快速排序
说明:
使用栈来实现
代码实现:
void QuickSortNonR(int* a,int left, int right) { stack<int> s; s.push(right); s.push(left); while(!s.empty()) { int begin = s.top(); //此时取得数是left; s.pop(); int end = s.top(); //此时取得数是right s.pop(); int div = PartSort(a,begin,end); //begin, div+1 //div-1,end if(begin < div1) { s.push(div-1); s.push(begin); } if(end > div-1) { s.push(end); s.push(div-1); } } }
4、快排的递归实现
void QuickSort(int* a,int left, int right) { //加入小区间优化 if(right-left < 20) { Insert(a+left,a+right-1); } else{ if(left < right) { int div = PartSort(a,left,right); QuickSort(a,left,div-1); QuickSort(a,div+1,right); } } }
5、快排的时间复杂度
当key为最大或最小的时候是O(N^2)
最好的是O(NlgN)
快排三种划分的代码
1、左右指针法int PartSort1(int* a, int left,int right) { //利用三数取中法进行优化,只做下面的两步就可以 //int key = GetMidIndex(a,left.right); //swap(a[key],a[right]); int key = right; while(left < right) { while((left<right) && (a[left] <= a[key])) left++; while((left<right) && (a[right] >= a[key])) right--; if(a[left] > a[right]) std::swap(a[left],a[right]); } std::swap(a[left],a[key]); return left; }
2、挖坑法
int PartSort3(int*a, int left,int right) { //注意:挖坑法要保存的是要填的值,而不是下标 int key = a[right]; while(left < right) { while(left < right && a[left] <= key) left++; if(left<right) a[right] = a[left]; while(left< right && a[right] >= key) right--; if(left<right) a[left] =a[right]; } a[left] = key; return left; }
3、前后指针法
int PartSort2(int* a, int left,int right) { int key = right; int cur = left; int pre = cur-1; while(cur < right) { if((a[cur] < a[key]) && (++pre != cur)) swap(a[pre],a[cur]); ++cur; } swap(a[++pre],a[right]); return pre; }
相关文章推荐
- 数据结构之单向链表操作1-(插入,删除,交换,反转,排序等操作)
- 数据结构排序-交换排序-冒泡排序
- 【数据结构】排序算法(二)之交换排序之快速排序(QuickSort)
- 【数据结构】排序算法(二)之交换排序之快速排序(QuickSort)
- 算法与数据结构之交换(SWAP)排序
- 数据结构-交换排序-冒泡排序
- 【数据结构】对一个数组按给定的下标排序,仅使用两两交换的方式,要求不能对数组进行扩容尽可能使用额外少的空间
- 数据结构-排序: 交换排序(冒泡排序法)
- 数据结构-排序: 交换排序(快速排序法)
- 数据结构几种交换排序
- 数据结构-排序: 交换排序(冒泡排序法)
- 数据结构例程——交换排序之冒泡排序
- 数据结构-排序算法之交换排序(冒泡排序快速排序)
- 数据结构-排序: 交换排序(快速排序法)
- 数据结构例程—— 交换排序之快速排序
- 数据结构-排序: 交换排序(快速排序法)
- 数据结构-排序: 交换排序(冒泡排序法)
- 数据结构 排序 交换排序
- 【数据结构】交换排序
- 数据结构 排序1 交换排序