C语言冒泡、插入法、选择排序算法分析
- 格式:doc
- 大小:41.50 KB
- 文档页数:4
算法-链表排序(冒泡、选择、插⼊)排序算法经典排序算法包括:冒泡、选择、和插⼊。
下⾯按照升序排序给出⼀句话解释:冒泡 -- 进⾏N-1次循环,每次循环从第⼀个元素开始,将此元素和其后元素⽐较,如果前者⼤,则互换位置,直到最后⼀个位置元素被⽐较,执⾏完毕则最⼤的⼀个元素在最后⼀个位置,类似⽔中⽓泡向上冒的过程,越是向上,⽓泡越⼤。
选择 -- 进⾏N-1次循环,每次循环,遍历所有未排序元素,定位最⼤的⼀个元素,将其放到尾部,则最后⼀个位置保证为最⼤元素。
定位的过程就是选择。
插⼊ -- 进⾏N-1次循环,每次循环,取出未排序的第⼀个元素,将此元素插⼊到⼀个新的有序列表中,插⼊过程为从有序列表中第⼀个元素开始,找到第⼀个⼤于待插⼊元素的元素,将待插⼊元素插⼊到此元素前。
数组形式的排序算法例⼦,见下⾯博⽂:本⽂给出单链表形式的排序代码:选择排序/***********************************************************************selecting sort method************************************************************************/// find specific node by strcmpfunc and detach it from listPT_NODE FindAndDetachNode(PT_NODE ptHeadNode, STRCMPFUNC strcmpfunc ){PT_NODE ptTargetNode = NULL;PT_NODE ptPreMax = NULL;PT_NODE ptCurNode = NULL;PT_NODE ptPreNode = NULL;ptTargetNode = ptHeadNode->next;ptPreMax = ptHeadNode;ptCurNode = ptHeadNode->next;ptPreNode = ptHeadNode;while( ptCurNode ){// current node string is larger than specific node string, record itif ( strcmpfunc(ptCurNode->str, ptTargetNode->str) ){ptTargetNode = ptCurNode;ptPreMax = ptPreNode;}ptPreNode = ptCurNode;ptCurNode = ptCurNode->next;}// specific node found, detach it from listif ( ptTargetNode ){ptPreMax->next = ptTargetNode->next;ptTargetNode->next = NULL;}// sort list by specific order by strcmpfuncvoid SortListWithSelectMethod(PT_NODE ptHeadNode, STRCMPFUNC strcmpfunc) {T_NODE tNewHead = {NULL, NULL};PT_NODE ptNode = NULL;// selection sort methodwhile( TRUE ){// find target node and detach it from listptNode = FindAndDetachNode(ptHeadNode, strcmpfunc);if ( !ptNode ){break;}// insert target node into new list from headInsertNode2ListHead(&tNewHead, ptNode);}// reset head node to new listptHeadNode->next = tNewHead.next;tNewHead.next = NULL;}冒泡排序/***********************************************************************bubble sort method************************************************************************/// bubble list by strcmpfunc and detach last from listPT_NODE BubbleAndDetachLast(PT_NODE ptHeadNode, STRCMPFUNC strcmpfunc) {PT_NODE ptCurNode = NULL;PT_NODE ptPreNode = NULL;PT_NODE ptNextNode = NULL;ptCurNode = ptHeadNode->next;ptPreNode = ptHeadNode;while( ptCurNode ){ptNextNode = ptCurNode->next;// reach list tailif ( !ptNextNode ){break;}// current node string is larger than next node string, swap itif ( strcmpfunc(ptCurNode->str, ptNextNode->str) ){ptPreNode->next = ptNextNode;ptCurNode->next = ptNextNode->next;ptNextNode->next = ptCurNode;// reset current node's previous nodeptPreNode = ptNextNode;}else{ptPreNode = ptCurNode;ptCurNode = ptCurNode->next;}}//detach current node from listptPreNode->next = NULL;// current node is the last node, return itreturn ptCurNode;}// bubble list and detach last from listptNode = BubbleAndDetachLast(ptHeadNode, strcmpfunc);if ( !ptNode ){break;}// insert max node into new list from headInsertNode2ListHead(&tNewHead, ptNode);}// reset head node to new listptHeadNode->next = tNewHead.next;tNewHead.next = NULL;}插⼊排序/***********************************************************************inserting sort method************************************************************************/PT_NODE DetachFirstNode(PT_NODE ptHeadNode){PT_NODE ptFirstNode = NULL;ptFirstNode = ptHeadNode->next;// detach first node from listif ( ptFirstNode ){ptHeadNode->next = ptFirstNode->next;}return ptFirstNode;}// insert node into list by inserting sort methodvoid InsertNode2ListByInsertMethod(PT_NODE ptHeadNode, PT_NODE ptNode, STRCMPFUNC strcmpfunc) {PT_NODE ptPrevNode = NULL;PT_NODE ptCurNode = NULL;ptPrevNode = ptHeadNode;ptCurNode = ptPrevNode->next;while( ptCurNode ){if ( strcmpfunc(ptCurNode->str, ptNode->str) ){ptPrevNode->next = ptNode;ptNode->next = ptCurNode;// insert ok, let's leavebreak;}else{ptPrevNode = ptCurNode;ptCurNode = ptCurNode->next;}}// current node is NULL, previous node is last node of list,// ie, insert not ok, the node shall be added to tailif ( !ptCurNode ){ptPrevNode->next = ptNode;ptNode->next = NULL;}}// get first node from listptNode = DetachFirstNode(ptHeadNode);if ( !ptNode ){break;}// insert the node into new list by inserting methodInsertNode2ListByInsertMethod(&tNewHead, ptNode, strcmpfunc); }// reset head node to new listptHeadNode->next = tNewHead.next;tNewHead.next = NULL;}。
c语言中排序的各种方法解析一、引言在计算机编程中,排序是一个重要的操作,它按照一定的顺序排列数据元素,使得数据元素按照从小到大的顺序排列。
在C语言中,有多种方法可以实现排序,包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。
这些排序算法都有各自的优缺点,适合不同的应用场景。
二、冒泡排序冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
算法步骤:1. 比较相邻的元素。
如果第一个比第二个大(升序),就交换它们两个。
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
这步做完后,最后的元素会是最大的数。
3. 针对所有的元素重复以上的步骤,除了最后一个。
4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
三、选择排序选择排序是一种简单直观的排序算法。
它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
算法步骤:1. 在未排序序列中找到最小元素,存放到排序序列的起始位置。
2. 再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。
3. 以此类推,直到所有元素均排序完毕。
四、插入排序插入排序的工作方式是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在实现上通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
五、快速排序快速排序使用了分治的原则,它在每一层划分都比前面方法有所改进和精进,当切分到两边的子序列长度都大于某个值时,或者一个大于一个小于这个值时再进行交换的操作来结束此层的递归过程。
这层的结果又成为下一层的两个子数组来处理,最后就得到递归式的最终结果。
c语言中的排序算法排序算法是计算机科学中非常重要的一个概念,它可以将一组无序的数据按照特定的规则进行排列,使得数据具有一定的有序性。
在C语言中,有多种排序算法可以实现这一功能。
本文将介绍一些常见的排序算法,并对它们的原理和实现进行详细的讲解。
一、冒泡排序冒泡排序是一种简单而常见的排序算法。
其基本思想是从待排序的数据序列的起始位置开始,依次比较相邻两个元素的大小,若发现逆序则交换它们的位置,直到整个序列有序。
冒泡排序的时间复杂度为O(n^2)。
二、选择排序选择排序是一种简单的排序算法,其基本思想是每次从待排序的数据序列中选择最小(或最大)的元素,将其放置在已排序序列的末尾,直到整个序列有序。
选择排序的时间复杂度为O(n^2)。
三、插入排序插入排序是一种简单而常用的排序算法,其基本思想是将待排序的数据序列分为已排序和未排序两部分,每次从未排序的部分中选择一个元素,并插入到已排序部分的适当位置,直到整个序列有序。
插入排序的时间复杂度为O(n^2)。
四、快速排序快速排序是一种高效的排序算法,其基本思想是选择一个基准元素,通过一趟排序将待排序的数据序列分割成独立的两部分,其中一部分的所有元素均小于(或大于)基准元素,然后再递归地对这两部分进行排序,直到整个序列有序。
快速排序的时间复杂度为O(nlogn)。
五、归并排序归并排序是一种高效的排序算法,其基本思想是将待排序的数据序列分成两个子序列,分别对这两个子序列进行排序,然后再将排好序的子序列合并成一个有序序列,直到整个序列有序。
归并排序的时间复杂度为O(nlogn)。
六、堆排序堆排序是一种高效的排序算法,其基本思想是将待排序的数据序列看成是完全二叉树的顺序存储结构,利用堆的性质进行排序。
堆排序的时间复杂度为O(nlogn)。
七、希尔排序希尔排序是一种高效的排序算法,其基本思想是将待排序的数据序列分成若干个子序列,对每个子序列进行直接插入排序,然后逐步缩小子序列的长度,最终使整个序列有序。
C语言中三种常见排序算法分析C语言中三种常见排序算法分析C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
那么C语言中三种常见排序算法的分析情况是怎样的呢。
以下仅供参考!一、冒泡法(起泡法)算法要求:用起泡法对10个整数按升序排序。
算法分析:如果有n个数,则要进行n-1趟比较。
在第1趟比较中要进行n-1次相邻元素的两两比较,在第j趟比较中要进行n-j次两两比较。
比较的顺序从前往后,经过一趟比较后,将最值沉底(换到最后一个元素位置),最大值沉底为升序,最小值沉底为降序。
算法源代码:# includemain(){int a[10],i,j,t;printf("Please input 10 numbers: ");/*输入源数据*/for(i=0;i<10;i++)scanf("%d",&a[i]);/*排序*/for(j=0;j<9;j++) /*外循环控制排序趟数,n个数排n-1趟*/for(i=0;i<9-j;i++) /*内循环每趟比较的次数,第j趟比较n-j次*/ if(a[i]>a[i+1]) /*相邻元素比较,逆序则交换*/{ t=a[i];a[i]=a[i+1];a[i+1]=t;}/*输出排序结果*/printf("The sorted numbers: ");for(i=0;i<10;i++)printf("%d ",a[i]);printf(" ");}算法特点:相邻元素两两比较,每趟将最值沉底即可确定一个数在结果的位置,确定元素位置的顺序是从后往前,其余元素可能作相对位置的调整。
可以进行升序或降序排序。
算法分析:定义n-1次循环,每个数字比较n-j次,比较前一个数和后一个数的大小。
冒泡插入选择排序解析以及信号量机制由于待会儿要出去吃饭,所以就不啰嗦其他东东咯,直奔主题吧!今天简单解析下三种排序算法,目的是要清楚永久滴记住它,另外讲下操作系统中的信号量机制。
冒泡算法:顾名思义,就是像水底冒泡泡一样,最上面那个泡泡是最大的,最下面的泡泡是最小的,当然,实际应用中大小因人而异。
我们都知道,每个算法都有其核心的东西,也就是核心方法,而对于冒泡排序来说,无非是那个两重循环,那怎么来理解这个两重循环呢?循环肯定是for啊for的啦,那怎么for呢?对于冒泡来说,第一层for我们可以这样子理解,就是需要确定几个泡泡的位置,这样子说吧,有一堆大小不一的泡泡,怎么实现大泡在上,小泡在下,那么确定一个泡泡的位置需要一次操作,那么如果有N个泡泡,需要几次操作呢?很容易理解,需要N-1次操作,之所以减一是因为,确定了第 N-1个泡泡之后,第N个就自然而然确定了,所以第N个是不用操作的。
接下来是第二个for了,第二个for 是确定需要交换的次数,直接算,我们无法很快得知,那么用一种迂回,如果已经确定了第2个泡泡,那么就只需要对其他泡泡进行N-2个泡泡进行交换排序了,即这个for中关联到第一个for的操作数,而对于交换,我们看成从上到下,那么始终都包含有第一个数和第二个数的交换,直到需要交换的下标达到最后已经确定位置的下标为止。
下面送上核心部分代码:(时间复杂度为O(n2))For(int i=0;i<length-1;i++){For(int k=length-1;k>i;k–)//k=length-1意思是下标最大的那个数,即最后一个数{If(arr[k]>a[k-1]){Temp=arr[k];Arr[k]=arr[k-1];Arr[k-1]=temp;}}}插入排序:对于插入排序来说,首先明白原理是一堆数,一个个来加入到新的数组中,即这个新数组原本是没有一个数,从一堆数中取一个数放进去,然后再取一个数,比较,大的放后面,小的放前面,以此类推,这种排序消耗的是来一个数和新数组的所有数进行比较,可以知道其时间复杂度是O(n2)。
C语言排序与查找算法在编程领域中,排序和查找算法是非常重要的基础知识。
掌握了这些算法,我们可以更高效地处理数据,提升程序运行效率。
本文将介绍一些常见的C语言排序和查找算法,帮助大家理解和应用这些算法。
一、排序算法1. 冒泡排序冒泡排序是一种简单直观的排序算法。
它通过相邻元素比较和交换的方式,将大的元素逐渐“冒泡”到右侧,实现排序的目的。
冒泡排序的时间复杂度为O(n^2)。
2. 插入排序插入排序是一种直接插入排序算法。
它将数组分为已排序和未排序两部分,每次从未排序序列中取一个元素,插入到已排序序列中的正确位置,通过不断重复这个过程,实现排序。
插入排序的时间复杂度为O(n^2)。
3. 选择排序选择排序是一种简单的选择排序算法。
它通过每次选择最小值或最大值,依次放在已排序序列的最后,将未排序部分不断缩小,最终完成排序。
选择排序的时间复杂度为O(n^2)。
4. 快速排序快速排序是一种高效的排序算法。
它通过选择一个基准元素,将数组分为两部分,一部分小于基准值,一部分大于基准值,然后分别对这两部分递归地进行排序,最终完成排序。
快速排序的平均时间复杂度为O(nlogn)。
二、查找算法1. 线性查找线性查找是一种简单直观的查找算法。
它从数组的第一个元素开始逐个比较,直到找到目标元素或遍历完整个数组。
线性查找的时间复杂度为O(n)。
2. 二分查找二分查找是一种高效的查找算法,但要求待查找的数组必须是有序的。
它通过不断将搜索范围缩小为原来的一半,直到找到目标元素或搜索范围为空。
二分查找的时间复杂度为O(logn)。
3. 哈希查找哈希查找是一种利用哈希函数进行查找的算法。
它通过将关键字通过哈希函数转换为数组的下标,然后在该下标位置进行查找,以快速定位目标元素。
哈希查找的平均时间复杂度为O(1),但要额外消耗存储空间。
结语通过学习排序和查找算法,我们可以对数据进行排序和查找操作,提升程序的效率和性能。
在实际编程中,根据数据规模和特点选择适当的排序和查找算法是非常重要的。
/*冒泡,插入,选择排序算法*/#include "stdio.h"#include "conio.h"# define max 10typedef int keytype;typedef struct{keytype key;int other;}node ;void maopao(node R[],int n) /*int maopao(node R[],int n)*/{int i,j;int exchang=0;for (i=max;i>1;i--){for (j=1;j<i;j++) /* {for (j=1;i<i;i++)*/{if (R[j].key>R[j+1].key)R[0].key=R[j].key; R[j].key=R[j+1].key; R[j+1].key=R[0].key;exchang=1;}if(exchang==0)break;}}void charu(node R[],int n){int i,j;for(i=2;i<=max;i++){R[0].key=R[i].key;for(j=i-1;R[j].key>R[0].key;j--)R[j+1].key=R[j].key;R[j+1].key=R[0].key ;}}void select (node R[],int n)int j,i,index;for(i=1;i<=max;i++){ index=i;for(j=i+1;j<=max;j++) /* index=i;for(j=i+1;j<=max;i++最后行不出来) */ if(R[j].key<R[index].key)index=j;if(index!=i){R[0].key=R[i].key;R[i].key=R[index].key;R[index].key=R[0].key;/* r[0].key=r[index].key;r[index].key=r[i].key;r[i].key=r[0].key;*/}}}main(){ int j;node r[max+1]={{0},{42},{12},{44},{24},{24},{2},{7},{21},{57},{6}};printf("\nmaopao is:\n");maopao(r,max);for (j=1;j<=max;j++){printf("%7d",r[j].key);}printf("\n\n\ncharu paixu is:\n");charu (r,max);for (j=1;j<=max;j++){printf("%5d",r[j].key);}printf("\n\n\n\nxuanze is:\n");select (r,max);/*若不写插入得法前,这里也是排序了,因为前面已经调用了*/ for (j=1;j<=max;j++){printf("%3d",r[j].key);}getch();。
C语言入门必学—10个经典C语言算法C语言是一种广泛使用的编程语言,具有高效、灵活和易学的特点。
它不仅在软件开发中被广泛应用,也是计算机科学专业的必修课。
在学习C语言的过程中,掌握一些经典的算法是非常重要的。
本文将介绍10个经典C语言算法,帮助读者更好地了解和掌握C语言。
一、冒泡排序算法(Bubble Sort)冒泡排序算法是最简单、也是最经典的排序算法之一。
它通过不断比较相邻的元素并交换位置,将最大(或最小)的元素逐渐“冒泡”到数组的最后(或最前)位置。
二、选择排序算法(Selection Sort)选择排序算法是一种简单但低效的排序算法。
它通过不断选择最小(或最大)的元素,并与未排序部分的第一个元素进行交换,将最小(或最大)的元素逐渐交换到数组的前面(或后面)。
三、插入排序算法(Insertion Sort)插入排序算法是一种简单且高效的排序算法。
它通过将数组分为已排序和未排序两个部分,依次将未排序部分的元素插入到已排序部分的合适位置。
四、快速排序算法(Quick Sort)快速排序算法是一种高效的排序算法。
它采用了分治的思想,通过将数组分为较小和较大两部分,并递归地对两部分进行排序,最终达到整个数组有序的目的。
五、归并排序算法(Merge Sort)归并排序算法是一种高效的排序算法。
它采用了分治的思想,将数组一分为二,递归地对两个子数组进行排序,并将结果合并,最终得到有序的数组。
六、二分查找算法(Binary Search)二分查找算法是一种高效的查找算法。
它通过不断将查找范围折半,根据中间元素与目标值的大小关系,缩小查找范围,最终找到目标值所在的位置。
七、递归算法(Recursive Algorithm)递归算法是一种通过自我调用的方式解决问题的算法。
在C语言中,递归算法常用于解决树的遍历、问题分解等情况。
八、斐波那契数列算法(Fibonacci Sequence)斐波那契数列是一列数字,其中每个数字都是前两个数字的和。
常用的c语言排序算法主要有三种即冒泡法排序、选择法排序、插入法排序。
一、冒泡排序冒泡排序:是从第一个数开始,依次往后比较,在满足判断条件下进行交换。
代码实现(以降序排序为例)#include<stdio.h>int main(){int array[10] = { 6,9,7,8,5,3,4,0,1,2 };int temp;for (int i = 0; i < 10; i++){//循环次数for (int j = 0; j <10 - i-1; j++){if (array[j] < array[j+1]){//前面一个数比后面的数大时发生交换temp = array[j];array[j] = array[j+1];array[j + 1] = temp;}}} //打印数组for (int i = 0; i < 10; i++) printf("%2d", array[i]); return 0;}}二、选择排序以升序排序为例:就是在指定下标的数组元素往后(指定下标的元素往往是从第一个元素开始,然后依次往后),找出除指定下标元素外的值与指定元素进行对比,满足条件就进行交换。
与冒泡排序的区别可以理解为冒泡排序是相邻的两个值对比,而选择排序是遍历数组,找出数组元素与指定的数组元素进行对比。
(以升序为例)#include<stdio.h>int main(){int array[10] = { 6,9,7,8,5,3,4,0,1,2 };int temp, index;for (int i = 0; i < 9; i++) {index = i;for (int j = i; j < 10; j++){if (array[j] < array[index])index = j;}if(i != index){temp = array[i]; array[i] = array[index]; array[index] = temp; }for(int i=0;i<10:i++) printf("%2d"array[i])return 0;}三、快速排序是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
C#冒泡排序法、插⼊排序法、选择排序法是数组等线性排列的数字从⼤到⼩或从⼩到⼤排序。
以从⼩到⼤排序为例。
数据 11, 35, 39, 30, 7, 36, 22, 13, 1, 38, 26, 18, 12, 5, 45, 32, 6, 21, 42, 23使⽤数组 int [] array 存储数字。
过程 (数组从⼩到⼤排序)思路循环都把最⼤的数放在最后⼀位,⽆序数字个数减1。
i 为当前任务位置,n 剩下的⽆序数字个数从第 0位开始,⽐较前后两位数字⼤⼤⼩,当 array[i] > array[i+1] 时,数值互换。
⼀个循环后,数值最⼤的已经存到数组最后⼀位。
⽆序数字个数 n-1 for (int j = array.Length - 1; j > 0; j--) //每排⼀次,剩下的⽆序数减⼀{for (int i = 0; i < j; i++) //⼀个for循环获得⼀个最⼤的数{if (array[i] > array[i + 1]) //数值互换{var sap = array[i];array[i] = array[i + 1];array[i + 1] = sap;}}}排序结果动图如下插⼊排序法插⼊排序算法是把⼀个数插⼊⼀个已经排序好的数组中。
例如把 22 插⼊到 [1,5,10,17,28,39,42] 中,结果 [1,5,10,17,22,28,39,42] 。
对数组使⽤插⼊排序法数组 int [] array = [11, 39, 35, 30, 7, 36, 22, 13, 1, 38, 26, 18, 12, 5, 45, 32, 6, 21, 42, 23];数组元素是⽆序,设定⼀个从⼤到⼩或从⼩到⼤的⽅向,第⼀位就是有序的[ 11 ],第⼀次插⼊: [11, 39, 35, 30, 7, 36, 22, 13, 1, 38, 26, 18, 12, 5, 45, 32, 6, 21, 42, 23]。
C语言中三种常见排序算法分析一、冒泡法(起泡法)算法要求:用起泡法对10个整数按升序排序。
算法分析:如果有n个数,则要进行n-1趟比较。
在第1趟比较中要进行n-1次相邻元素的两两比较,在第j趟比较中要进行n-j次两两比较。
比较的顺序从前往后,经过一趟比较后,将最值沉底(换到最后一个元素位置),最大值沉底为升序,最小值沉底为降序。
算法源代码:# include <stdio.h>main(){int a[10],i,j,t;printf("Please input 10 numbers: ");/*输入源数据*/for(i=0;i<10;i++)scanf("%d",&a[i]);/*排序*/for(j=0;j<9;j++) /*外循环控制排序趟数,n个数排n-1趟*/for(i=0;i<9-j;i++) /*内循环每趟比较的次数,第j趟比较n-j次*/if(a[i]>a[i+1]) /*相邻元素比较,逆序则交换*/{ t=a[i];a[i]=a[i+1];a[i+1]=t;}/*输出排序结果*/printf("The sorted numbers: ");for(i=0;i<10;i++)printf("%d ",a[i]);printf("\n");}算法特点:相邻元素两两比较,每趟将最值沉底即可确定一个数在结果的位置,确定元素位置的顺序是从后往前,其余元素可能作相对位置的调整。
可以进行升序或降序排序。
算法分析:定义n-1次循环,每个数字比较n-j次,比较前一个数和后一个数的大小。
然后交换顺序。
二、选择法算法要求:用选择法对10个整数按降序排序。
算法分析:每趟选出一个最值和无序序列的第一个数交换,n个数共选n-1趟。
第i趟假设i为最值下标,然后将最值和i+1至最后一个数比较,找出最值的下标,若最值下标不为初设值,则将最值元素和下标为i的元素交换。
算法源代码:# include <stdio.h>main(){int a[10],i,j,k,t,n=10;printf("Please input 10 numbers:");for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<n-1;i++) /*外循环控制趟数,n个数选n-1趟*/{k=i;/*假设当前趟的第一个数为最值,记在k中*/for(j=i+1;j<n;j++) /*从下一个数到最后一个数之间找最值*/if(a[k]<a[j]) /*若其后有比最值更大的*/k=j;/*则将其下标记在k中*/if(k!=i) /*若k不为最初的i值,说明在其后找到比其更大的数*/{ t=a[k]; a[k]=a[i]; a[i]=t; } /*则交换最值和当前序列的第一个数*/}printf("The sorted numbers: ");for(i=0;i<10;i++)printf("%d ",a[i]);printf("\n");}算法特点:每趟是选出一个最值确定其在结果序列中的位置,确定元素的位置是从前往后,而每趟最多进行一次交换,其余元素的相对位置不变。
可进行降序排序或升序排序。
算法分析:定义外部n-1次循环,假设第一个为最值,放在参数中,在从下一个数以后找最值若后面有比前面假设的最值更大的就放在k中,然后在对k进行分析。
若k部位最初的i值。
也就是假设的i不是最值,那么就交换最值和当前序列的第一个数三、插入法算法要求:用插入排序法对10个整数进行降序排序。
算法分析:将序列分为有序序列和无序列,依次从无序序列中取出元素值插入到有序序列的合适位置。
初始是有序序列中只有第一个数,其余n-1个数组成无序序列,则n个数需进n-1次插入。
寻找在有序序列中插入位置可以从有序序列的最后一个数往前找,在未找到插入点之前可以同时向后移动元素,为插入元素准备空间。
算法源代码:# include <stdio.h>main(){int a[10],i,j,t;printf("Please input 10 numbers: ");for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=1;i<10;i++) /*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/{t=a[i]; /*将待插入数暂存于变量t中*/for( j=i-1 ; j>=0 && t>a[j] ; j-- )/*在有序序列(下标0 ~ i-1)中寻找插入位置*/a[j+1]=a[j]; /*若未找到插入位置,则当前元素后移一个位置*/a[j+1]=t; /*找到插入位置,完成插入*/}printf("The sorted numbers: ");for(i=0;i<10;i++)printf("%d ",a[i]);printf("\n");}算法特点:每趟从无序序列中取出第一个数插入到有序序列的合适位置,元素的最终位置在最后一趟插入后才能确定位置。
也可是先用循环查找插入位置(可从前往后或从后往前),再将插入位置之后的元素(有序列中)逐个后移一个位置,最后完成插入。
该算法的特点是在寻找插入位置的同时完成元素的移动。
因为元素的移动必须从后往前,则可将两个操作结合在一起完成,提高算法效率。
仍可进行升序或降序排序。
几种排序的概念在数据的处理中,数据的排序是相当重要的。
它可以使数据更有条理,方便数据的其它处理。
在学习生活中,也经常用到数据的排序,如:考完试后个人成绩的排名、运动会上班级总分的排名、常规评比分数的排序。
这些排序当然不是人工完成的,它们大多数是用excel软件来代劳的。
那么excel软件的排序的本质方法是什么呢?这就是我所要研究学习的内容。
通过查阅图书、教材,搜索资料、教程,我了解到:排序的本质其实就是比较。
对于任何一种排序方法来说,比较都是其最重要的一个组成部分。
但它也是最简单的部分,因为排序方法的好坏、快慢取决于比较的方法、比较的顺序和比较的次数,而与比较本身关系不大。
那么,排序具体有那些方法呢?下面介绍几种我研究学习了的算法。
一、冒泡排序已知一组无序数据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]就以升序排列了。
优点:稳定,比较次数已知;缺点:慢,每次只能移动相邻两个数据,移动数据的次数多。
二、选择排序已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。
首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。
再比较a[1]与a[3]的值,若a[1]大于a[3]则交换两者的值,否则不变。
再比较a[1]与a[4],依此类推,最后比较a[1]与a[n]的值。
这样处理一轮后,a[1]的值一定是这组数据中最小的。
再将a[2]与a[3]~a[n]以相同方法比较一轮,则a[2]的值一定是a[2]~a[n]中最小的。
再将a[3]与a[4]~a[n]以相同方法比较一轮,依此类推。
共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。
优点:稳定,比较次数与冒泡排序一样,数据移动次数比冒泡排序少;缺点:相对之下还是慢。
三、插入排序已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、b[2]、……b[m],需将二者合并成一个升序数列。
首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来a[x]的位置这就完成了b[1]的插入。
b[2]~b[m]用相同方法插入。
(若无数组a,可将b[1]当作n=1的数组a)优点:稳定,快;缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。
四、缩小增量排序由希尔在1959年提出,又称希尔排序。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。
发现当n不大是,插入排序的效果很好。
首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组依此类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。
优点:快,数据移动少;缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。
五、快速排序快速排序是冒泡排序的改进版,是目前已知的最快的排序方法。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。
首先任取数据a[x]作为基准。
比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据<a[x],a[k+1]~a[n]中的每一个数据>a[x],然后采用分治的策略分别对a[1]~a[k-1]和a[k+1]~a[n]两组数据进行快速排序。
优点:极快,数据移动少;缺点:不稳定。
经过一段时间的学习和编程,我已对上述几种排序方法熟练掌握或有所了解。
在此基础上,经过我的思考和实践,我研究出了一种新的排序算法:分段插入排序。
分段插入排序已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、b[2]、……b[m],需将二者合并成一个升序数列。
先将数组a分成x等份(x<<n),每等份有n/x个数据。
将每一段的第一个数据先储存在数组c中:c[1]、c[2]、……c[x]。