冒泡排序-----选择排序
冒泡排序速记口诀(降序):
N个数字来排序,两两相比大靠前,
外层循环N-1,内层循环N-1-i.
如果要升序,
只要把程序中的if (a[j] < a[j + 1])
小于号换成大于号就行了
定义数组:int array[10]={4,2,6 ,9 ,22,1,100};
冒泡排序的过程如下:
第一次冒泡:
将第一个数4与第二个数2比较,4>2则位置不变,再将第二个数2与第三个数6进行比较,
2<6,则将2与6交换位置。
以此类推,2<9,2与9交换位置,
2<22,2与22交换位置,
2>1,则位置不变,
1<100,则1与100交换位置。
此趟结束后数组为{4,6,9,22,2,100,1}
第二次冒泡:
将4与6进行比较,4<6,交换位置,
4<9交换位置,
4<22交换位置,
4>2,位置不变,
2<100交换位置,
2>1位置不变
此趟结束后数组为{6,9,22,4,100,2,1}
第三次冒泡:
将6与9比较, 6<9交换位置,
6<22交换位置,
6>4位置不变, 4<100交换位置,
4>2位置不变,
2>1位置不变
此趟结束后数组为{9,22,6,100,4,2,1}
第四次冒泡:
将9与22比较,9<22交换位置,
9>6位置不变,
6<100交换位置,此后位置不变。
此趟结束后数组为{22,9,100,6,4,2,1}
第五次冒泡:
22与9比较位置不变,9与100比较,交换位置,此后位置不变。
此趟结束后数组为{22,100,9,6,4,2,1}
第六次冒泡:
22与100比较,交换位置,此后位置不变。
此趟结束后数组为{100,22,9,6,4,2,1}
#n为数组长度
其实现代码为
int i,j,t;
int a[n];
for( i=0;i<n-1;i++)
{
for( j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
{ t=a[j]; a[j]=a[j+1]; a[j+1]=t; }
}
}
#include void main() { int a[10]; int i,j,t; printf("输入10个整数:\n"); for( i = 0; i < 10; i ++ ) scanf("%d",&a[ i ]); //依次输入10个整数 for( j = 0; j < 9; j ++ ) //进行9轮排序 即n-1次 { for( i = 0; i < 9-j; i ++) //每轮进行n-1-j 次比较,最多n-1-j 次交换 if( a[ i ] > a[ i + 1 ] ) { t = a[ i ] ; a[ i ] = a[ i + 1 ]; //小的沉底,大的上浮 a[ i + 1 ] = t; } } printf("排序结果:"); for( i = 0; i < 10; i ++ ) //依次输出排序结果 printf("%d\t",a[ i ]); printf("\n"); }
//冒泡排序 #include <stdio.h> #define N 100 void sort(int n,int a[]) { int i,j,t ; for(i=0;i<n-1 ;i++) for(j=0;j<n-1-i ;j++) if(a[j]>a[j+1]) { t=a[j] ;a[j]=a[j+1] ;a[j+1]=t ;} } int main ( ) { int a[N],n ,i ; scanf("%d",&n); for(i=0;i<n ;i++) scanf("%d",&a[i]); sort(n,a) ; for(i=0;i<n-1 ;i++) printf("%d",a[i]); printf("%d\n",a[i]); } //冒泡排序 #include <stdio.h> void sort(int n,int a[]) { int i,j,t ; for(i=0;i<n-1 ;i++) for(j=0;j<n-1-i ;j++) if(a[j]>a[j+1]) { t=a[j] ;a[j]=a[j+1] ;a[j+1]=t ;} } int main ( ) { int b[5]={ 0 ,5, 3, 1 ,2 },i ; sort(5,b) ; for(i=0;i<5 ;i++) printf("%d ",b[i]); } //冒泡排序 #include <stdio.h> void sort(int n,int a[]); // 声明 //void sort(int n,int b[]); int main ( ) { int b[5]={ 0 ,5, 3, 1 ,2 },i ; sort(5,b) ; for(i=0;i<5 ;i++) printf("%d ",b[i]); } void sort(int n,int a[]) { int i,j,t ; for(i=0;i<n-1 ;i++) for(j=0;j<n-1-i ;j++) if(a[j]>a[j+1]) { t=a[j] ;a[j]=a[j+1] ;a[j+1]=t ;} } //冒泡排序 #include <stdio.h> void sort(int b[]); // 声明 //void sort(int a[]); int main ( ) { int b[5]={ 0 ,5, 3, 1 ,2 },i ; sort(b) ; for(i=0;i<5 ;i++) printf("%d ",b[i]); } void sort(int a[]) { int i,j,t ; for(i=0;i<5-1 ;i++) for(j=0;j<5-1-i ;j++) if(a[j]>a[j+1]) { t=a[j] ;a[j]=a[j+1] ;a[j+1]=t ;} } //冒泡排序 #include <stdio.h> void sort(int a[]); // 声明 int main ( ) { int a[5]={ 0 ,5, 3, 1 ,2 },i ; sort(a) ; for(i=0;i<5 ;i++) printf("%d ",a[i]); } void sort(int a[]) { int i,j,t ; for(i=0;i<5-1 ;i++) for(j=0;j<5-1-i ;j++) if(a[j]>a[j+1]) { t=a[j] ;a[j]=a[j+1] ;a[j+1]=t ;} } 与冒泡排序相比,选择排序的平均时间复杂度比冒泡排序稍高。
基本思想: 每一趟从待排序的元素中选出最小(或者最大)的一个元素顺序放在已排好序的数列的 最后,
直到全部待排序的数据元素排完。
选择排序是不稳定的排序方法,
N个记录的文件的直接选择排序可经过N-1趟直接选择排序得到有序结果。
示例如下: 定义数组a[]={13,4,8,2,11,67,0}
第一趟:a[]={0,4,8,2,11,67,13}
第二趟: a[]={0,2,8,4,11,67,13}
第三趟:a[]={0,2,4,8,11,67,13}
第四趟:a[]={0,2,4,8,11,67,13}
第五趟:a[]={0,2,4,8,11,67,13}
第六趟:a[]={0,2,4,8,11,13,67}
算法描述如下:
int a[n];//定义数组,长度为n int i,j,t;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{ t=a[i]; a[i]=a[j]; a[j]=t; }
}
}
#include void main() {int i,j,min,temp,a[11]; printf("enter data:\n"); for(i=1;i<=10;i++) {printf("a[%d]=",i); scanf("%d",&a[i]);//输入10个数 } printf("\n"); printf("The orginal numbers:\n"); for(i=1;i<=10;i++) printf("%5d",a[i]);//输出这10个数 printf("\n"); for(i=1;i<=9;i++)//以下8行是对10个数排序 {min=i; for(j=i+1;j<=10;j++) if(a[min]>a[i]) min=j;//以下是进行对换 temp=a[i]; a[i]=a[min]; a[min]=temp; } printf("\n The sorted numbers:\n") for(i=1;i<=10;i++) printf("%5d",a[i]);//输出已排好的10个数 printf("\n"); }
#include <iostream> //选择 using namespace std; void f(int a[],int n) { int i,j ,min,p,t ; for(i=0 ; i<n-1 ;i++) { min=a[i] ; p=i ; for(j=i+1 ; j<n ; j++) if(a[j]<min) min=a[i],p=j ; // if(a[j]<min) min=a[i] ; p=j ; if(p!=i) t=a[p] ,a[p]=a[i] ,a[i]=t ; } } int main( ) { int a[10],i ; for(i=0 ; i<10 ; i++) cin>>a[i] ; f(a,10) ; for(i=0 ; i<10 ; i++) cout<<a[i]<<endl ; } #include <iostream> //选择 using namespace std; void f(int a[],int n) { int i,j ,min,p,t ; for(i=0 ; i<n-1 ;i++) { min=a[i] ; p=i ; for(j=i+1 ; j<n ; j++) if(a[j]<min) min=a[i], p=j ; if(p!=i) t=a[p] ,a[p]=a[i] ,a[i]=t ; } } int main( ) { int N ; cin>> N; int a[N]; int i ; for(i=0 ; i<N ; i++) cin>>a[i] ; f(a,N) ; for(i=0 ; i<N ; i++) cout<<a[i]<<endl ; } #include <stdio.h> //选择 void sort(int a[]) ; int main ( ) { int a[5]={ 9,6,8,3,-1},i ; sort(a) ; for(i=0 ;i<=4 ;i++) printf("%4d",a[i]) ; } void sort(int a[]) { int i,j,t,k ; for(j=0 ; j<4 ;j++) // j<3 ,4,5 ???? { k=j ; for(i=j ;i<5 ;i++) if(a[i]<a[k]) k=i ; t=a[k] ,a[k]=a[j] ,a[j]=t ; } } #include <stdio.h> ////选择 void sort(int a[]) { int i,j,t,k,n ; for(j=0 ; j<3 ;j++) // j<3 ,4,5 ???? { k=j ; for(i=j ;i<5 ;i++) if(a[i]<a[k]) k=i ; t=a[k] ,a[k]=a[j] ,a[j]=t ; } } int main ( ) { int a[5]={ 9,6,8,3,-1},i ; sort(a) ; for(i=0 ;i<=4 ;i++) printf("%4d",a[i]) ; }
C 冒泡排序 冒泡排序描述 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 冒泡排序对n个项目需要O(n2)的比较次数,且可以原地排序(in-place)。尽管这个算法是最简单了解和实作的排序算法之一,但它对于少数元素之外的数列排序是很没有效率的。 冒泡排序是与插入排序拥有相等的执行时间,但是两种法在需要的交换次数却很大地不同。在最坏的情况,冒泡排序需要O(n2)次交换,而插入排序只要最多O(n)交换。天真的冒泡排序实作(类似下面)通常会对已经排序好的数列拙劣地执行(O(n2)),而插入排序在这个例子只需要O(n)个运算。因此很多现代的算法教科书避免使用冒泡排序,而用插入排序取代之。冒泡排序如果能在内部循环第一次执行时,使用一个旗标来表示有无需要交换的可能,也有可能把最好的复杂度降低到O(n)。在这个情况,在已经排序号的数列就无交换的需要。若在每次走访数列时,把走访顺序和比较大小反过来,也可以些微地改进效率。 冒泡排序算法的运作如下: 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 1.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 2.针对所有的元素重复以上的步骤,除了最后一个。 3.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 示例代码 复制代码 1 #include <stdlib.h> 2 #include <stdio.h> 3 4 void bubble_sort(int a[], const int size) 5 { 6 int flag = 0; 7 int temp = 0; 8 int i; 9 for(i = 0; i < size - 1; i ++) { 10 flag = 1; 11 int j; 12 for(j = 0; j < size - i -1; j ++) { 13 if(a[j] > a[j + 1]) { 14 temp = a[j]; 15 a[j] = a[j + 1]; 16 a[j + 1] = temp; 17 flag = 0; 18 } 19 } 20 if(flag) 21 break; 22 } 23 } 24 25 int main() 26 { 27 int number[] = {5,3,8,4,1,7,9,2,0,6}; 28 bubble_sort(number, sizeof(int_array) / sizeof(int)); 29 int i; 30 for(i = 0; i < sizeof(int_array) / sizeof(int); i ++) 31 printf("%d\n", number[i]); 32 } 复制代码 输出结果 复制代码 0 1 2 3 4 5 6 7 8 9 复制代码 原理 已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的。再对a[1]~a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。 优劣 优点:稳定;缺点:慢,每次只能移动相邻两个数据。
C 选择排序 选择排序描述 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。 示例代码 复制代码 1 #include <stdlib.h> 2 #include <stdio.h> 3 4 void selection_sort(int data[], int count) 5 { 6 int i, j, min, temp; 7 for(i = 0; i < count -1; i ++) { 8 /*find the minimum*/ 9 min = i; 10 for(j = i + 1; j < count; j ++) 11 if(data[j] < data[min]) 12 min = j; 13 temp = data[i]; 14 data[i] = data[min]; 15 data[min] = temp; 16 printf("%d\n", min); 17 } 18 } 19 20 int main() 21 { 22 int number[] = {5,3,8,4,1,7,9,2,0,6}; 23 selection_sort(number, 10); 24 int i; 25 for(i = 0; i < 10; i ++) 26 printf("%d\n",number[i]); 27 exit(0); 28 } 复制代码 输出结果 复制代码 0 1 2 3 4 5 6 7 8 9 复制代码 算法分析 选择排序的交换操作介于0和(n − 1)次之间。选择排序的比较操作为n(n − 1) / 2次之间。选择排序的赋值操作介于0和3(n − 1)次之间。比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。 交换次数O(n),最好情况是,已经有序,交换0次;最坏情况是,逆序,交换n-1次。 交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。 原理 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(很多教科书都说选择排序是不稳定的,但是,完全可以将其实现成稳定的排序方法)。 n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果: ①初始状态:无序区为R[1..n],有序区为空。 ②第1趟排序 在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。 ③第i趟排序 第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(1≤i≤n-1)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。 这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。 优劣 优点:移动数据的次数已知(n-1次);缺点:比较次数多,不稳定。