排序(插入排序,希尔排序,归并排序,快速排序)
来源:互联网 发布:linux怎么进入编辑 编辑:程序博客网 时间:2024/05/16 10:02
1.插入排序:每一步将一个待排序的元素按照其关键字值的大小插入到已排序序列的适当位置,知道待排序元素插入完为止。
(1).核心代码:
void sort(int a[],int n)//插入排序 { int i,j; int temp; for(i = 0;i<n;i++) { int j = i; int temp = a[i]; while(j>0 && temp < a[j-1])//逐个比较,temp>=a[j-1]时,j便是应该插入的位置 { a[j] = a[j-1];//往后移,找到插入位置时可以马上插入 j--; } a[j] = temp; }}
(2).例题:将序列 3,1,4,1,5,9,2,6,5用插入排序排位升序列。
#include <stdio.h>void sort(int a[],int n)//插入排序 { int i,j; int temp; for(i = 0;i<n;i++) { int j = i; int temp = a[i]; while(j>0 && temp < a[j-1]) //逐个比较,temp>=a[j-1]时,j便是应该插入的位置 { a[j] = a[j-1];//往后移,找到插入位置时可以马上插入 j--; } a[j] = temp; }} int main(){ int a[9] = { 3,1,4,1,5,9,2,6,5}; sort(a,9); for(int i = 0;i<9;i++) { printf("%d\t",a[i]); } }
运行结果:
2.简单排序算法的下界:
(1、插入排序的运行时间时O(I+N),其中I为原始数组中的逆序数。
(2、N个互异的数的数组平均逆序数时N(N-1)/4。
(3、通过交换相邻元素进行排序的任何算法平均需要 欧(N平方)时间
3.希尔排序:既有插入排序的简单的优点,也克服了只能交换相邻元素的缺点。
(1.主要代码:
void shell_sort(int a[],int n){ int i,j,gap; for(gap = n/2;gap > 0; gap /= 2) { for(i = 0;i < gap;i++) { for(j = i;j < n;j += gap) { if(a[j] < a[j-gap])//如果逆序,则寻找插入的位置 { int temp = a[j]; int k = j-gap; while(k>=0 && a[k] > temp) { a[k+gap] = a[k]; k -= gap; } a[k+gap] = temp; } } } }}
(2.完整代码:
#include <stdio.h>void shell_sort(int a[],int n){ int i,j,gap; for(gap = n/2;gap > 0; gap /= 2) { for(i = 0;i < gap;i++) { for(j = i;j < n;j += gap) { if(a[j] < a[j-gap])//如果逆序,则寻找插入的位置 { int temp = a[j]; int k = j-gap; while(k>=0 && a[k] > temp) { a[k+gap] = a[k]; k -= gap; } a[k+gap] = temp; } } } }}int main(){ int a[5] = {2,4,5,1,3}; shell_sort(a,5); for(int i = 0;i<5;i++) { printf("%d\t",a[i]); }}
运行结果:
4.归并排序:将两个子序列归并为有序的序列,运用了分而治之、递归的思想,排序算法稳定。
(1.主要代码:
void merge(int a[],int temp[],int l,int r,int rightend){ int leftend = r-1;//leftend是左边的终点,r是右边的起点,假设两边是挨着的 int temp1 = l; int num = rightend-l+1; while(l <= leftend && r <= rightend) { if(a[l] < a[r]) temp[temp1++] = a[l++]; else temp[temp1++] = a[r++]; } while(l <= leftend) temp[temp1++] = a[l++]; while(r <= rightend) temp[temp1++] = a[r++];//实际情况中只有一个while满足 for(int i = 0;i<num;i++,rightend--) { a[rightend] = temp[rightend]; } }void mysort(int a[],int temp[],int l,int rightend){ int center; if(l < rightend) { center = (l+rightend)/2; mysort(a,temp,l,center); mysort(a,temp,center+1,rightend);//递归排序 merge(a,temp,l,center+1,rightend);//将两个有序空间排序成一个有序空间 }}
(2.完整代码:
#include <stdio.h>void merge(int a[],int temp[],int l,int r,int rightend){ int leftend = r-1;//leftend是左边的终点,r是右边的起点,假设两边是挨着的 int temp1 = l; int num = rightend-l+1; while(l <= leftend && r <= rightend) { if(a[l] < a[r]) temp[temp1++] = a[l++]; else temp[temp1++] = a[r++]; } while(l <= leftend) temp[temp1++] = a[l++]; while(r <= rightend) temp[temp1++] = a[r++];//实际情况中只有一个while满足 for(int i = 0;i<num;i++,rightend--) { a[rightend] = temp[rightend]; } }void mysort(int a[],int temp[],int l,int rightend){ int center; if(l < rightend) { center = (l+rightend)/2; mysort(a,temp,l,center); mysort(a,temp,center+1,rightend);//递归排序 merge(a,temp,l,center+1,rightend);//将两个有序空间排序成一个有序空间 }}int main(){ int a[5] = {23,3,1,2,4}; int temp[5]; mysort(a,temp,0,4); for(int i = 0;i<5;i++) { printf("%d\t",a[i]); }}
运行结果:
5.快速排序:快速排序也是一种分值的递归算法,对于规模较小的排序,应采用简单排序(如:插入、冒泡排序等),对于大规模的使用快速排序更好。
(1、主元的选取:选择合适的主元,会使代码更加优化,更快
//选主元 int median(int a[],int left,int right){ int center = (left+right)/2; if(a[left] > a[right]) swap(&a[left],&a[right]); if(a[left] > a[center]) swap(&a[left],&a[center]); if(a[right] < a[center]) swap(&a[right],&a[center]); swap(&a[center],&a[right-1]); //将主元元放到a[right-1],只考虑a[left+1]到a[right-2]; return a[right-1];}
(2、核心代码:
void quick_sort(int a[],int left,int right){ if(left<right)//如果right>=left,则停止递归 { int med = median(a,left,right); int i = left, j = right - 1; for( ; ; ) { while ( a[ ++i ] < med ) { } while ( a[ --j ] > med ) { } if ( i < j ) swap( &a[i], &a[j] ); else break; } swap( &a[i], &a[ right-1 ] ); quick_sort( a, left, i-1 ); quick_sort( a, i+1, right ); } } void Quick(int a[],int n)//规范排序函数 { quick_sort(a,0,n-1); }
(3、完整代码:
#include <stdio.h>void swap(int *a,int *b){ int temp; temp = *a; *a = *b; *b = temp;}//选主元 int median(int a[],int left,int right){ int center = (left+right)/2; if(a[left] > a[right]) swap(&a[left],&a[right]); if(a[left] > a[center]) swap(&a[left],&a[center]); if(a[right] < a[center]) swap(&a[right],&a[center]); swap(&a[center],&a[right-1]); //将主元元放到a[right-1],只考虑a[left+1]到a[right-2]; return a[right-1];}void quick_sort(int a[],int left,int right){ if(left<right)//如果right>=left,则停止递归 { int med = median(a,left,right); int i = left, j = right ; for( ; ; ) { while ( a[ ++i ] < med ) { } while ( a[ --j ] > med ) { } if ( i < j ) swap( &a[i], &a[j] ); else break; } swap( &a[i], &a[ right-1 ] ); quick_sort( a, left, i-1 ); quick_sort( a, i+1, right ); } } void Quick(int a[],int n)//规范排序函数 { quick_sort(a,0,n-1); } int main(){ int a[5] = {5,4,3,2,1}; Quick(a,5); for(int i = 0;i<5;i++) { printf("%d\t",a[i]); }}
运行结果:
阅读全文
0 0
- 排序(插入排序,希尔排序,归并排序,快速排序)
- 插入排序、希尔排序、堆排序、归并排序、快速排序
- 排序:插入,希尔,堆,快速,归并排序
- 常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)
- 排序(希尔排序,堆排序,归并排序,快速排序)
- 经典排序算法(希尔排序,归并排序,快速排序,插入排序)
- 常用的排序算法:插入排序,希尔排序,冒泡排序,选择排序,快速排序,归并排序
- C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- 冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序java实现
- 插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序、归并排序
- 冒泡排序,插入排序,快速排序,归并排序,堆排序,选择排序,希尔排序
- 冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序六大排序大总结
- Python 排序 冒泡排序 希尔排序 快速排序 插入排序 选择排序 归并排序
- 插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序
- 常见比较排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)
- 数据结构-排序算法详解(插入排序,希尔排序,堆排序,归并排序,快速排序,桶式排序)
- 排序算法二(归并排序、快速排序、希尔排序)
- POJ 3250 Bad Hair Day
- Idea 导入module后,代码中jar包找不到引用
- mapbox-gl-js学习之重新编译【零基础】
- 两种求解斐波那契数算法的时间比较
- conn 不为空,但是conn已经关闭(No operations allowed after connection closed)
- 排序(插入排序,希尔排序,归并排序,快速排序)
- Java编程之十进制转二进制算法
- JavaScript入门(三)
- 数据结构与算法2
- es 记录
- Hyperspectral Band Selection by Multitask Sparsity Puisuit
- Interrupt
- PHP之SQL注入
- CodeForces 624C【二分图染色】