C语言四种排序算法时间复杂度比较
- 格式:doc
- 大小:318.00 KB
- 文档页数:10
c语言查找算法
C语言是一种广泛使用的编程语言,它具有高效、简单、易学等特点,因此在各个领域都有广泛的应用。
在C语言中,查找算法是一种非常
重要的算法,它可以帮助我们在大量数据中快速查找到我们需要的数据。
下面我们将详细介绍C语言中的查找算法。
一、顺序查找算法
顺序查找算法是一种最简单的查找算法,它的基本思想是从数据的第
一个元素开始逐个比较,直到找到目标元素或者遍历完整个数据。
顺
序查找算法的时间复杂度为O(n),其中n为数据的长度。
二、二分查找算法
二分查找算法也称为折半查找算法,它的基本思想是将数据分成两部分,然后判断目标元素在哪一部分中,再在该部分中继续进行查找,
直到找到目标元素或者确定目标元素不存在。
二分查找算法的时间复
杂度为O(logn),其中n为数据的长度。
三、哈希查找算法
哈希查找算法是一种利用哈希表进行查找的算法,它的基本思想是将数据通过哈希函数映射到哈希表中,然后在哈希表中查找目标元素。
哈希查找算法的时间复杂度为O(1),但是它需要额外的空间来存储哈希表。
四、树查找算法
树查找算法是一种利用树结构进行查找的算法,它的基本思想是将数据构建成一棵树,然后在树中查找目标元素。
树查找算法的时间复杂度为O(logn),但是它需要额外的空间来存储树结构。
总结:
C语言中的查找算法有顺序查找算法、二分查找算法、哈希查找算法和树查找算法。
不同的算法适用于不同的场景,我们可以根据实际情况选择合适的算法来进行查找。
在实际应用中,我们还可以将不同的算法进行组合,以达到更高效的查找效果。
【数据结构】常见排序算法复杂度相关概念1、稳定排序(stable sort)和⾮稳定排序稳定排序是指所有相等的数经过某种排序算法操作后仍然能保持它们在排序之前的相对次序。
反之就是⾮稳定排序。
2、内排序(internal sorting)和外排序(external sorting)在排序过程中,所有需要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序;在排序过程中,只有部分数被调⼊内存,并借助内存调整数在外存中的存放顺序排序⽅法称为外排序。
排序算法【冒泡排序】(Bubble Sort)冒泡排序⽅法是最简单的排序⽅法。
这种⽅法的基本思想是,将待排序的元素看作是竖着排列的“⽓泡”,较⼩的元素⽐较轻,从⽽要往上浮。
在冒泡排序算法中我们要对这个“⽓泡”序列处理若⼲遍。
所谓⼀遍处理,就是⾃底向上检查⼀遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。
如果发现两个相邻元素的顺序不对,即“轻”的元素在下⾯,就交换它们的位置。
显然,处理⼀遍之后,“最轻”的元素就浮到了最⾼位置;处理⼆遍之后,“次轻”的元素就浮到了次⾼位置。
在作第⼆遍处理时,由于最⾼位置上的元素已是“最轻”元素,所以不必检查。
⼀般地,第i遍处理时,不必检查第i⾼位置以上的元素,因为经过前⾯i-1遍的处理,它们已正确地排好序。
冒泡排序是稳定的。
算法时间复杂度是O(n2)。
【选择排序】(Selection Sort)选择排序的基本思想是对待排序的记录序列进⾏n-1遍的处理,第 i 遍处理是将[i..n]中最⼩者与位置 i 交换位置。
这样,经过 i 遍处理之后,前 i 个记录的位置已经是正确的了。
选择排序是不稳定的。
算法复杂度是O(n2 )。
【插⼊排序】(Insertion Sort)插⼊排序的基本思想是,经过i-1遍处理后,L[1..i-1]⼰排好序。
第i遍处理仅将L插⼊L[1..i-1]的适当位置,使得L[1..i]⼜是排好序的序列。
要达到这个⽬的,我们可以⽤顺序⽐较的⽅法。
c语言冒号排序法冒泡排序法是经典的排序算法之一,其基本思想是通过不断交换相邻的元素,使较小的元素逐渐向前移动,从而将整个序列按照从小到大的顺序排序。
冒泡排序法的过程可以用以下的伪代码来描述:for (i = 0; i < n; i++) {for (j = 0; j < n - i - 1; j++) {if (a[j] > a[j + 1]) {swap(a[j], a[j + 1]);}}}其中,n为序列的长度,a为待排序的序列,swap函数用于交换两个元素的值。
上述代码的思路很简单,就是不断比较相邻的两个元素大小,如果前面的元素比后面的元素大,则交换它们的位置。
冒泡排序法的时间复杂度为O(n^2),实现比较简单,但是对于大规模数据的排序效率较低,不过在实际应用中,冒泡排序法还是有一定用处的。
除了上述的基本冒泡排序法,还有一种改进版的冒泡排序法,即冒号排序法。
冒泡排序法每次都需要比较相邻的两个元素,而冒号排序法则将序列分成了两个部分,分别为有序序列和无序序列。
通过不断将无序序列中最大的元素冒号移动到有序序列的末尾,最终就能将整个序列按照从小到大的顺序排序完毕。
冒号排序法的过程可以用以下的伪代码来描述:for (i = 0; i < n - 1; i++) {is_sorted = true;for (j = 0; j < n - i - 1; j++) {if (a[j] > a[j + 1]) {swap(a[j], a[j + 1]);is_sorted = false;}}if (is_sorted) {break;}}其中,is_sorted为布尔型变量,用于判断序列是否已经有序。
在指针i不断向后移动的过程中,指针j从头开始遍历无序序列,并将最大的元素逐渐冒号移动到有序序列的末尾。
如果在一轮冒号排序中,没有发生交换,说明序列已经有序,排序过程可以提前终止。
c语言中的算法C语言是一种广泛使用的编程语言,它具有强大的算法实现能力。
算法是解决问题的一种有序的方法和步骤,它可以应用于不同的领域,如排序、搜索、图形处理等。
本文将介绍C语言中常见的一些算法。
我们来看排序算法。
排序算法是将一组数据按照特定的顺序进行排列的过程。
在C语言中,常见的排序算法有冒泡排序、选择排序、插入排序、快速排序等。
冒泡排序是一种简单的排序算法,它通过不断地比较相邻两个元素的大小,将较大的元素逐步交换到数组的末尾。
选择排序是一种简单但低效的排序算法,它通过不断选择最小的元素并将其放置在正确的位置上来排序。
插入排序是一种将待排序序列分为已排序和未排序两部分的排序算法,它通过依次将未排序序列中的元素插入到已排序序列的正确位置上来排序。
快速排序是一种非常高效的排序算法,它通过选择一个基准元素,然后将待排序序列不断地分割成较小和较大两部分,并对这两部分进行递归排序,最后将结果合并起来。
我们来看搜索算法。
搜索算法是在一个数据集中查找某个特定元素的过程。
在C语言中,常见的搜索算法有线性搜索、二分搜索、哈希表等。
线性搜索是一种简单但低效的搜索算法,它通过遍历整个数据集来寻找目标元素。
二分搜索是一种高效的搜索算法,它要求数据集是有序的,并通过不断将数据集分成两半来查找目标元素。
哈希表是一种通过将关键字映射到一个唯一的索引位置来快速查找元素的数据结构,它在C语言中可以通过使用散列函数和数组来实现。
然后,我们来看图形处理算法。
图形处理算法是对图像进行处理和分析的算法。
C语言中常见的图形处理算法有图像滤波、边缘检测、图像压缩等。
图像滤波是一种通过对图像的像素进行重新计算来改变图像外观的算法,它可以用于去除噪声、增强图像细节等。
边缘检测是一种用于检测图像中边缘的算法,它通过寻找图像中亮度变化较大的区域来定位边缘。
图像压缩是一种通过减少图像数据的存储空间来减小图像文件大小的算法,它可以通过舍弃冗余信息和使用压缩编码技术来实现。
当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。
快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;1. 插入排序—直接插入排序(Straight Insertion Sort)基本思想:将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。
即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
要点:设立哨兵,作为临时存储和判断数组边界之用。
直接插入排序示例:如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。
所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
算法的实现:效率:时间复杂度:O(n^2).其他的插入排序有二分插入排序,2-路插入排序。
2. 插入排序—希尔排序(Shell`s Sort)希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。
希尔排序又叫缩小增量排序基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
操作方法:1.选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;2.按增量序列个数k,对序列进行k 趟排序;3.每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。
仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
希尔排序的示例:算法实现:我们简单处理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数即:先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。
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 语言查找算法一、线性查找线性查找也称为顺序查找,是最简单的一种查找算法。
它的原理是从数据集的第一个元素开始,逐个比较每个元素,直到找到目标值或者遍历完整个数据集。
由于它的查找过程是按顺序进行的,所以时间复杂度为O(n),其中n为数据集的大小。
二、二分查找二分查找是一种高效的查找算法,但要求数据集必须是有序的。
它的原理是先确定数据集的中间元素,然后将目标值与中间元素进行比较。
如果目标值等于中间元素,则查找成功;如果目标值小于中间元素,则在左半部分继续查找;如果目标值大于中间元素,则在右半部分继续查找。
通过每次将数据集缩小一半的方式,可以快速地找到目标值。
二分查找的时间复杂度为O(log n),其中n为数据集的大小。
三、哈希查找哈希查找是一种基于哈希表的查找算法,它通过将数据元素与其对应的哈希值进行关联,从而实现快速查找。
哈希表是一种以键值对形式存储数据的数据结构,通过哈希函数将键映射到对应的索引位置。
在查找时,只需要通过哈希函数计算目标值的哈希值,并在哈希表中查找对应的索引位置即可。
哈希查找的平均时间复杂度为O(1),但在最坏情况下可能达到O(n),其中n为数据集的大小。
四、二叉查找树二叉查找树(Binary Search Tree,BST)是一种二叉树的数据结构,它具有以下特点:对于任意节点,其左子树中的所有节点的值都小于该节点的值,右子树中的所有节点的值都大于该节点的值。
通过这种有序性,可以快速地进行查找操作。
在查找时,从根节点开始,根据目标值与当前节点的大小关系,递归地在左子树或右子树中查找。
二叉查找树的平均时间复杂度为O(log n),但在最坏情况下可能达到O(n),其中n为二叉查找树中节点的个数。
c语言提供了多种查找算法,可以根据不同的需求选择合适的算法。
线性查找适用于数据量较小且无序的情况;二分查找适用于数据量较大且有序的情况;哈希查找适用于需要快速定位的情况;二叉查找树适用于需要频繁插入和删除节点的情况。
冒泡排序 c语言
冒泡排序是一种基本的排序方法,也是学习算法和数据结构的基础之一。
它的原理非常简单,就是不断地比较相邻的两个数,如果它们的顺序不对就交换它们的位置,直到所有的数都排好序为止。
在C语言中,冒泡排序的实现也很简单,可以通过两重循环来实现。
首先,外层循环控制排序的次数,一共需要进行n-1次排序,其中n是待排序数列的长度。
内层循环则负责比较和交换相邻的两个数,每次比较的范围都会缩小,因为每次排序都会将当前最大的数“沉”到数组的末尾。
下面是冒泡排序的C语言代码示例:
```c
void bubble_sort(int arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
```
这段代码中,arr是待排序数组的指针,n是数组的长度。
函数首先定义了两个循环变量i和j,分别表示当前排序的次数和当前比较的位置。
在内层循环中,如果相邻的两个数的顺序不对,就交换它们的位置,直到整个数组都排好序为止。
冒泡排序虽然简单,但是效率比较低,时间复杂度为O(n^2),在处理大规模的数据时会比较慢。
因此,在实际应用中,更多地采用其他高效的排序算法,比如快速排序、归并排序等。
c语言基础算法知识C语言基础算法知识概述:C语言作为一种广泛应用的编程语言,其基础算法知识对于程序员来说至关重要。
本文将从常见的算法知识入手,介绍C语言中常用的算法及其应用。
一、排序算法排序算法是计算机科学中最基础也是最常用的算法之一。
常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序等。
这些算法的实现原理各不相同,但都能对一组数据进行排序。
1. 冒泡排序冒泡排序是一种简单直观的排序算法,它重复地遍历待排序的元素,比较相邻的两个元素并将它们交换顺序,直至整个序列有序。
2. 选择排序选择排序是一种简单直观的排序算法,它每次从待排序的数据中选择最小(或最大)的元素,将其放到已排序序列的末尾。
3. 插入排序插入排序是一种简单直观的排序算法,它将待排序的数据分为已排序和未排序两部分,每次从未排序中取出一个元素插入到已排序的合适位置,直至整个序列有序。
4. 快速排序快速排序是一种高效的排序算法,它通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有元素都比另一部分的元素小,然后对这两部分继续进行排序,直至整个序列有序。
5. 归并排序归并排序是一种稳定的排序算法,它采用分治策略,将待排序的数据不断二分,然后对子序列进行排序,最后将排序好的子序列合并成一个有序序列。
二、查找算法查找算法是在一组数据中寻找指定元素的算法。
常见的查找算法有线性查找、二分查找、哈希查找等。
1. 线性查找线性查找是一种简单直观的查找算法,它从待查找的数据中依次比较每个元素,直到找到目标元素或遍历完整个序列。
2. 二分查找二分查找是一种高效的查找算法,它要求待查找的数据必须是有序的,通过每次将查找范围缩小一半,直到找到目标元素或查找范围为空。
3. 哈希查找哈希查找是一种快速的查找算法,它通过将关键字映射到哈希表中的位置,以实现快速定位目标元素。
三、递归算法递归算法是一种重要的算法思想,它通过函数自身的调用来解决问题。
1、方案设计: 我这次实验通过随机生成30000个随机数,把随机数存到数组中,用这同一组随机数据分别进行四种排序,直接插入排序、直接选择排序、冒泡排序和快速排序。还通过了调用txt文件把运算所需时间导出,分别输出各个算法所需用时并对用时时长再进行冒泡排序算出用时最短的算法。 2、程序代码: #include #include #include #include #include #define N 30000
void Wrong() //输入错误 { printf("\n语法错误,请重新输入!\n"); getchar(); } void Disp(int a[]) //清屏 { int i; system("cls"); for(i=0; i{ if((i-1)%10==9) printf("\n"); printf("%-7d",a[i]); } }
void InsertSort(int a[],int p) //直接插入排序算法 { int i,j,temp; for(i=1; i{ temp=a[i]; for(j=i; j>0&&a[j-1]>temp; j--) a[j]=a[j-1]; a[j]=temp; }
} void SelectSort(int a[],int p) //选择排序算法 {
int i,j,k; for(i=0; i{ k=i; for(j=i+1; jif(a[j]k=j; if(k!=i) { int temp; temp=a[k]; a[k]=a[i]; a[i]=temp; } }
} void BubbleSort(int a[],int p) //冒泡排序算法 {
int i,j,temp; for (i=0; i{ for (j=N-1; j>i; j--) //比较,找出本趟最小关键字的记录 if (a[j]{ temp=a[j]; //进行交换,将最小关键字记录前移 a[j]=a[j-1]; a[j-1]=temp; } }
} void quicksort(int a[],int n,int p) //快速排序算法 {
int i,j,low,high,temp,top=-1; struct node { int low,high; } st[N]; top++; st[top].low=0; st[top].high=n-1; while(top>-1) { low=st[top].low; high=st[top].high; top--; i=low; j=high; if(low{ temp=a[low]; while(i!=j) { while(itemp)j--; if(i{ a[i]=a[j]; i++; } while(iif(i{ a[j]=a[i]; j--; } } a[i]=temp; top++; st[top].low=low; st[top].high=i-1; top++; st[top].low=i+1; st[top].high=high; } } }
double TInsertSort(int a[],int p)//计算直接插入排序算法用时 { int i; int b[N]; for(i=0; ib[i]=a[i]; LARGE_INTEGER m_liPerfFreq= {0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart= {0}; QueryPerformanceCounter(&m_liPerfStart); InsertSort(b,p); LARGE_INTEGER liPerfNow= {0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; if(p!=6) { Disp(b); getchar(); } printf("\n用直接插入排序法用的时间为%f秒;",time); FILE *fp; fp=fopen("直接插入排序.txt","w");
for(i=0; ifprintf(fp,"%d ",b[i]);
fclose(fp); return(time); } double TSelectSort(int a[],int p)//计算选择排序用时 { int i; int b[N]; for(i=0; ib[i]=a[i]; LARGE_INTEGER m_liPerfFreq= {0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart= {0}; QueryPerformanceCounter(&m_liPerfStart); SelectSort(b,p); if(p!=6) { Disp(b); getchar(); } LARGE_INTEGER liPerfNow= {0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; printf("\n用直接选择排序法用的时间为%f秒;",time);
FILE *fp; fp=fopen("直接选择排序.txt","w");
for(i=0; ifprintf(fp,"%d ",b[i]); fclose(fp); return(time); }
double TBubbleSort(int a[],int p)//计算冒泡排序算法用时 { int i; int b[N]; for(i=0; ib[i]=a[i]; LARGE_INTEGER m_liPerfFreq= {0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart= {0}; QueryPerformanceCounter(&m_liPerfStart); BubbleSort(b,p); LARGE_INTEGER liPerfNow= {0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; if(p!=6) { Disp(b); getchar(); } printf("\n用冒泡排序法用的时间为%f秒;",time); FILE *fp; fp=fopen("冒泡排序.txt","w");
for(i=0; ifprintf(fp,"%d ",b[i]); fclose(fp); return(time); }
double Tquicksort(int a[],int n,int p)//计算快速排序算法用时 { int i; int b[N]; for(i=0; ib[i]=a[i]; LARGE_INTEGER m_liPerfFreq= {0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart= {0}; QueryPerformanceCounter(&m_liPerfStart); quicksort(b,N,p); LARGE_INTEGER liPerfNow= {0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; if(p!=6) { Disp(b); getchar(); } printf("\n用快速排序法用的时间为%f秒;",time); FILE *fp; fp=fopen("快速排序.txt","w"); for(i=0; ifprintf(fp,"%d ",b[i]); fclose(fp); return(time); }
void BubleSort(double a[]) //时间数组的冒泡排序 { int i,j; double temp; for(i=1; i<6; i++) {