数据结构之排序大集合(下)(选择、堆、基数、归并,链表排序)
2018-01-26 14:24
525 查看
(1)选择排序
算法思想:每次从待排序序列中选出最小值,和待排序序列第一个值交换。
不稳定(因为有跳跃式的数据交换)
时间复杂度:O(n^2) 性能 优于冒泡排序
空间复杂度:O(1)
优化:竞标排序(两两打擂台)很少见到
构成满二叉树时间复杂度:O(nlogn) 空间复杂度:O(n)
(2)堆排序()
简单选择排序的升级
大根堆排序思路:将待排序的序列构造成一个大根堆,此时,整个序列的最大值就是堆顶的根结点,将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个
元素中的次小值,如此反复执行,得到一个有序序列。
堆分为大根堆和小根堆两种
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大根堆,或者每个结点的值都小于或等于其左右孩子结点的值,称为小根堆
构建堆的时间复杂度:O(n)
重建堆的时间复杂度:O(nlogn)
总的时间复杂度:O(nlogn)
空间复杂度:O(1)
堆排序是一种不稳定的排序算法,不适合待排序序列个数较少的情况。
(3)归并排序
归并的定义:合并、并入,将两个或两个以上的有序表组合成一个新的有序表**归并排序:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列长度是1,然后两两归并,得到【n/2】个长度为2或1的有序子序列,
再两两归并…….如此重复,直至得到一个长度为n 的有序序列为止,**这种排序方法称为 2路归并排序。
递归实现:时间复杂度:O(nlogn)
空间复杂度:O(n+logn)
非递归实现:空间复杂度:O(n)
**归并排序是一种比较占内存,但却效率高,且稳定的算法。
使用归并排序,尽量考虑用非递归。**
(4)基数排序(桶排序)针对于多关键字排序算法
算法思想:数字的话都是0—-9 准备10个桶。将数据按照一定规则先进先出(队列)
不需要关键字之间相互比较
空间复杂度:O(n) d*n
时间复杂度:O(n)
越有序越快
(5)链表排序(考试可能会考)
链表排序可以用冒泡排序实现(快速、插入、堆排序不合适)选择法排序也可以
算法思想:每次从待排序序列中选出最小值,和待排序序列第一个值交换。
不稳定(因为有跳跃式的数据交换)
时间复杂度:O(n^2) 性能 优于冒泡排序
空间复杂度:O(1)
void SelectSort(int *arr,int len) { int min;//值不好保存,要保存下标 int j; int tmp; for(int i= 0;i<len-1;i++) { min =i; for(j =i+1;j<len;j++) { if(arr[min]>arr[j]) { min = j; } } if(i != min) { tmp = arr[i]; arr[i] = arr[min 4000 ]; arr[min] = tmp; } } }
优化:竞标排序(两两打擂台)很少见到
构成满二叉树时间复杂度:O(nlogn) 空间复杂度:O(n)
(2)堆排序()
简单选择排序的升级
大根堆排序思路:将待排序的序列构造成一个大根堆,此时,整个序列的最大值就是堆顶的根结点,将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个
元素中的次小值,如此反复执行,得到一个有序序列。
堆分为大根堆和小根堆两种
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大根堆,或者每个结点的值都小于或等于其左右孩子结点的值,称为小根堆
构建堆的时间复杂度:O(n)
重建堆的时间复杂度:O(nlogn)
总的时间复杂度:O(nlogn)
空间复杂度:O(1)
堆排序是一种不稳定的排序算法,不适合待排序序列个数较少的情况。
//一次堆调整 void Adjust(int *arr,int start,int end)//O(logn) { int tmp = arr[start]; int parent = start; for(int i=2*start+1;i<=end;i=2*i+1)// { //父找子 if((i+1<=end) && (arr[i]<arr[i+1])) { ++i; }//i为左右孩子较大值的下标 if(tmp < arr[i]) { arr[parent] = arr[i]; parent = i; } else { break; } } arr[parent] = tmp; } void HeapSort(int *arr,int len)//O(nlog),,O(1),不稳定 { int i; for(i=(len-1-1)/2;i>=0;i--)//第一次建大根堆,O(nlogn) { //父找根 Adjust(arr,i,len-1); } int tmp; for(i=0;i<len-1;i++)//O(nlogn) { tmp = arr[0]; arr[0] = arr[len-1-i]; arr[len-1-i] = tmp;//将根和最后的一个值交换 Adjust(arr,0,len-1-i-1);//进行堆调整,不包括最后一个 } }
(3)归并排序
归并的定义:合并、并入,将两个或两个以上的有序表组合成一个新的有序表**归并排序:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列长度是1,然后两两归并,得到【n/2】个长度为2或1的有序子序列,
再两两归并…….如此重复,直至得到一个长度为n 的有序序列为止,**这种排序方法称为 2路归并排序。
递归实现:时间复杂度:O(nlogn)
空间复杂度:O(n+logn)
非递归实现:空间复杂度:O(n)
**归并排序是一种比较占内存,但却效率高,且稳定的算法。
使用归并排序,尽量考虑用非递归。**
void Merge(int *arr,int len,int gap)//gap为归并段的长度 { int low1 = 0;//第一个归并段的起始下标,下标可取 int high1 = low1+gap-1;//第一个归并段的结束下标,下标可取 int low2 =high1+1;// 第二个归并段的起始下标,下标可取 int high2 = low2+gap<len?low2+gap-1:len-1;//第二个归并段的结束下标,下标可取 int *brr = (int*)malloc(len*sizeof(int)); assert(brr!=NULL); int i=0;//brr下标 while(low2<len)//保证有两个归并段 { while(low1<=high1 && low2<=high2) { if(arr[low1]<=arr[low2]) { brr[i++] = arr[low1++]; } else { brr[i++] = arr[low2++]; } } while(low1<=high1) { brr[i++] = arr[low1++]; } while(low2<=high2) { brr[i++] = arr[low2++]; } low1 = high2+1; high1 = low1+gap-1; low2 = high1+1; high2 =low2+gap<len-1?low2+gap-1:len-1; } //处理只有一个归并段的数据 while(low1<len) { brr[i++] = arr[low1++]; } for(int i=0;i<len;i++) { arr[i] = brr[i]; } free(brr); } void MergeSort(int *arr,int len) { for(int i=1;i<len;i*=2) { Merge(arr,len,i); } }
(4)基数排序(桶排序)针对于多关键字排序算法
算法思想:数字的话都是0—-9 准备10个桶。将数据按照一定规则先进先出(队列)
不需要关键字之间相互比较
空间复杂度:O(n) d*n
时间复杂度:O(n)
越有序越快
(5)链表排序(考试可能会考)
链表排序可以用冒泡排序实现(快速、插入、堆排序不合适)选择法排序也可以
void ListSort() { int tmp; for(Node *p = plist->next;p->next!=NULL;p=p->next) { for(Node *q = plist->next;q->next != NULL;q=q->next) { if(q->data>q->next->data) { tmp = q->data; q->data = q->next->data; q->next->data = tmp; } } } }
相关文章推荐
- 从零开始_学_数据结构(六)——排序(冒泡、插入、希尔、简单选择、归并、快速)
- C语言中数据结构之链表归并排序实例代码
- 【数据结构与算法基础】单链表及其应用基数排序 / Singly Linked List and radix sort
- 数据结构排序问题---选择---希尔---归并
- 数据结构之排序大集合(下)(选择、堆、基数、归并,链表排序)
- 数据结构实验之排序五:归并求逆序数
- 数据结构问题---链表运算集合
- SDUT_2119 数据结构实验之链表四:有序链表的归并
- 数据结构与算法 4:排序算法,选择/插入/冒泡/希尔/快速/归并
- 数据结构之链表排序
- 数据结构(14)——插入排序、交换排序、选择排序、归并排序和基数排序算法的比较
- 【数据结构与算法】归并排序
- 【数据结构与算法】内部排序之二:冒泡排序和选择排序(改进优化,附完整源码)
- SDUTACM 数据结构实验之排序五:归并求逆序数
- 数据结构之线性表的静态单链表存储结构(应用求集合(A-B)&&(B-A))
- 数据结构与算法——冒泡排序、选择排序和快速排序
- 数据结构基础7.7:基数排序
- 数据结构之有序链表的归并
- 数据结构实验之排序五:归并求逆序数
- 【数据结构与算法】【排序】简单选择排序的代码实现