常见经典排序算法(C语言)1希尔排序 二分插入法 直接插入法 带哨兵的直接排序法 冒泡排序 选择排序 快速排
- 格式:docx
- 大小:23.83 KB
- 文档页数:8
一插入排序1.1 直接插入排序基本思想:每次将一个待排序额记录按其关键码的大小插入到一个已经排好序的有序序列中,直到全部记录排好序。
图解:1.//直接顺序排序2.void InsertSort(int r[], int n)3.{4.for (int i=2; i<n; i++)5. {6. r[0]=r[i]; //设置哨兵7.for (int j=i-1; r[0]<r[j]; j--) //寻找插入位置8. r[j+1]=r[j]; //记录后移9. r[j+1]=r[0];10. }11.for(int k=1;k<n;k++)12. cout<<r[k]<<" ";13. cout<<"\n";14.}1.2 希尔排序基本思想是:先将整个待排序记录序列分割成若干个子序列,在在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
图解:代码实现:[cpp]view plain copy1.<span style="font-size:14px;">//希尔排序2.void ShellSort(int r[], int n)3.{4.int i;5.int d;6.int j;7.for (d=n/2; d>=1; d=d/2) //以增量为d进行直接插入排序8. {9.for (i=d+1; i<n; i++)10. {11. r[0]=r[i]; //暂存被插入记录12.for (j=i-d; j>0 && r[0]<r[j]; j=j-d)13. r[j+d]=r[j]; //记录后移d个位置14. r[j+d]=r[0];15. }16. }17.for(i=1;i<n;i++)18. cout<<r[i]<<" ";19. cout<<"\n";20.}</span>二交换排序2.1 起泡排序起泡排序是交换排序中最简单的排序方法,其基本思想是:两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。
C语言所有内部排序算法冒泡法,选择法,插入法,快排法,希尔,归并,... 1冒泡法:#include<stdio.h>#include<stdlib.h>void mao_pao(int *a,int n){int i,j,temp,flag;for(i=0;i<n-1&&flag;++i){flag=0;for(j=0;j<n-1;++j){if(a[j]>a[j+1]){flag=1;temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}}}void main(){int *a,i,n;a=(int *)malloc(100);if(NULL==a){printf("allocation failture\n");exit(1);}printf("请输入你要排序的元素的个数\n");scanf("%d",&n);printf("现在开始输入%d个元素\n",n);for(i=0;i!=n;++i)scanf("%d",&a[i]);mao_pao(a,n);printf("排序后为:\n");for(i=0;i!=n;++i)printf("%d ",a[i]);printf("\n");free(a);}2,选择排序法#include<stdio.h>#include<stdlib.h>void xuan_zhe(int *a,int n) {int i,j,temp,max;for(i=0;i<n-1;++i){max=i;for(j=i+1;j<n;++j){if(a[j]<a[max])max=j;}if(i!=max){temp=a[i];a[i]=a[max];a[max]=temp;}}}void main(){int *a,i,n;a=(int *)malloc(100);if(NULL==a){printf("allocation failture\n");exit(1);}printf("请输入你要排序的元素的个数\n"); scanf("%d",&n);printf("现在开始输入%d个元素\n",n); for(i=0;i!=n;++i)scanf("%d",&a[i]);xuan_zhe(a,n);printf("排序后为:\n");for(i=0;i!=n;++i)printf("%d ",a[i]);printf("\n");free(a);}3,插入排序#include<stdio.h>#include<stdlib.h>void cha_ru(int *a,int n) {int i,j,temp;for(i=0;i<n-1;++i){temp=a[i+1];for(j=i;j>=0&&temp<a[j];--j) a[j+1]=a[j];a[++j]=temp;}}void main(){int *a,i,n;a=(int *)malloc(100);if(NULL==a){printf("allocation failture\n");exit(1);}printf("请输入你要排序的元素的个数\n"); scanf("%d",&n);printf("现在开始输入%d个元素\n",n); for(i=0;i!=n;++i)scanf("%d",&a[i]);cha_ru(a,n);printf("排序后为:\n");for(i=0;i!=n;++i)printf("%d ",a[i]);printf("\n");free(a);}4..快速排序#include<stdio.h>#include<stdlib.h>void kuai_pai(int *a,int low,int high){int left,right,middle,i,j,temp;left=low;right=high;middle=(left+right)/2;while(left<right){while(left<high&&a[left]<a[middle]) left++;while(right>low&&a[right]>a[middle]) right--;if(left<=right){temp=a[left];a[left]=a[right];a[right]=temp;left++;right--;}}if(left<high)kuai_pai(a,left,high);if(right>low)kuai_pai(a,low,right);}void main(){int *a,i,n;a=(int *)malloc(100);if(NULL==a){printf("allocation failture\n");exit(1);}printf("请输入你要排序的元素的个数\n"); scanf("%d",&n);printf("现在开始输入%d个元素\n",n); for(i=0;i!=n;++i)scanf("%d",&a[i]);kuai_pai(a,0,n-1);printf("排序后为:\n");for(i=0;i!=n;++i)printf("%d ",a[i]);printf("\n");free(a);}5..shell排序#include<stdio.h>#include<stdlib.h>void shell(int *a,int n){int gap,i,j,temp;for(gap=n/2;gap>0;gap=gap/2)for(i=gap;i<n;i++)for(j=i-gap;j>=0&&a[j]>a[j+gap];j=j-gap) {temp=a[j];a[j]=a[j+gap];a[j+gap]=temp;}}void main(){int *a,i,n;a=(int *)malloc(100);if(NULL==a){printf("allocation failture\n");exit(1);}printf("请输入你要排序的元素的个数\n"); scanf("%d",&n);printf("现在开始输入%d个元素\n",n); for(i=0;i!=n;++i)scanf("%d",&a[i]);shell(a,n);printf("排序后为:\n");for(i=0;i!=n;++i)printf("%d ",a[i]);printf("\n");free(a);}6.二路归并排序#include<stdio.h>#include<stdlib.h>void gui_bin(int *a,int *b,int k,int n) {int l1,l2,i,j,u1,u2,l=0;l1=0;while(l1+k<n){l2=l1+k;u1=l2-1;u2=(l2+k-1<n)?l2+k-1:n-1;i=l1;j=l2;while(i<=u1&&j<=u2){if(a[i]<=a[j])b[l++]=a[i++];elseb[l++]=a[j++];}while(i<=u1)b[l++]=a[i++];while(j<=u2)b[l++]=a[j++];l1=u2+1;}for(i=l1;i<n;++i)b[l++]=a[i];}void main(){int *a,*b,i,n,k=1;a=(int *)malloc(100);if(NULL==a){printf("allocation failture\n");exit(1);}b=(int *)malloc(100);if(NULL==b){printf("allocation failture\n");exit(1);}printf("请输入你要排序的元素的个数\n"); scanf("%d",&n);printf("现在开始输入%d个元素\n",n); for(i=0;i!=n;++i)scanf("%d",&a[i]);while(k<n){gui_bin(a,b,k,n);for(i=0;i<n;++i)a[i]=b[i];k=k*2;}printf("排序后为:\n");for(i=0;i!=n;++i)printf("%d ",a[i]);printf("\n");free(a);free(b);}7.堆排序思想是,跟节点都比他们的儿子节点都大,之后从第一个非叶子节点开始到最上的跟节点,依次求其的跟节点,最上的根节点就是值最大的点,这样取得最大值之后,继续求根节点,就能得到一个有序序列。
使⽤C语⾔实现12种排序⽅法⽬录1.冒泡排序2.插⼊排序3.折半插⼊排序4.希尔排序5.选择排序6.鸡尾酒排序7.堆排序8.快速排序9.归并排序10.计数排序11.桶排序12.基数排序1.冒泡排序思路:⽐较相邻的两个数字,如果前⼀个数字⼤,那么就交换两个数字,直到有序。
时间复杂度O(n^2),稳定性:这是⼀种稳定的算法。
代码实现:void bubble_sort(int arr[],size_t len){size_t i,j;for(i=0;i<len;i++){bool hasSwap = false; //优化,判断数组是否已经有序,如果有序可以提前退出循环for(j=1;j<len-i;j++){ //这⾥j<len-i是因为最后⾯的肯定都是最⼤的,不需要多进⾏⽐较if(arr[j-1]>arr[j]){ //如果前⼀个⽐后⼀个⼤swap(&arr[j-1],&arr[j]); //交换两个数据hasSwap = true;}}if(!hasSwap){break;}}}2.插⼊排序思路:把⼀个数字插⼊⼀个有序的序列中,使之仍然保持有序,如对于需要我们进⾏排序的数组,我们可以使它的前i个数字有序,然后再插⼊i+1个数字,插⼊到合适的位置使之仍然保持有序,直到所有的数字有序。
时间复杂度:O(n^2) 稳定性:稳定的算法代码实现:void insert_sort(int arr[],int len){int i,j;for(i=1;i<len;i++){int key = arr[i]; //记录当前需要插⼊的数据for(j= i-1;i>=0&&arr[j]>key;j--){ //找到插⼊的位置arr[j+1] = arr[j]; //把需要插⼊的元素后⾯的元素往后移}arr[j+1] = key; //插⼊该元素}}3.折半插⼊排序思路:本质上是插⼊排序,但是通过半分查找法找到插⼊的位置,让效率稍微快⼀点。
C语言基本算法C语言是一种广泛使用的编程语言,用于开发各种应用程序和系统。
算法是编程的核心部分,是解决问题的方法和步骤的描述。
在C语言中,有许多基本算法可以用来解决简单级别的问题。
下面我将介绍几种常见的C语言基本算法。
1.线性查找算法线性查找算法是一种简单的查找算法,它从数组的第一个元素开始顺序地比较,直到找到目标元素或遍历完整个数组。
这个算法的时间复杂度是O(n)。
```cint linearSearch(int arr[], int n, int target)for (int i = 0; i < n; i++)if (arr[i] == target)return i;}}return -1;```这个算法接受一个整数数组arr、数组的大小n和目标元素target 作为输入,并返回目标元素在数组中的索引,如果未找到则返回-12.冒泡排序算法冒泡排序是一种简单的排序算法,它通过多次循环比较和交换相邻元素来排序。
每次循环都将最大的元素冒泡到数组的末尾。
这个算法的时间复杂度是O(n^2)。
```cvoid bubbleSort(int arr[], int n)for (int i = 0; i < n-1; i++)for (int j = 0; j < n-i-1; j++)if (arr[j] > arr[j+1])int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}```这个算法接受一个整数数组arr和数组的大小n作为输入,并将数组按升序排序。
3.二分查找算法二分查找算法是一种高效的查找算法,它使用分治策略将有序数组分为两部分,并选择中间元素进行比较。
如果中间元素等于目标元素,则返回中间元素的索引;否则,如果中间元素大于目标元素,则在左侧部分继续查找;如果中间元素小于目标元素,则在右侧部分继续查找。
这个算法的时间复杂度是O(logn)。
简单算法c语言
C语言中的算法是程序设计的基础,也是我们在编写程序时必须掌握
的技能之一。
简单算法是指那些基本的、常用的、易于理解和实现的
算法,如排序、查找、递归等。
一、排序算法
1.冒泡排序
冒泡排序是一种简单的排序算法,其思想是将相邻两个元素比较大小,如果前面比后面大,则交换位置,直到整个序列有序为止。
2.选择排序
选择排序是一种简单直观的排序算法,其思想是从未排序序列中找到
最小元素,放到已排好序列的末尾。
3.插入排序
插入排序是一种简单直观的排序算法,其思想是将未排好序列中每一
个元素插入到已排好序列中正确位置上。
二、查找算法
1.线性查找
线性查找又称顺序查找,其思想是从头到尾遍历整个数组或列表,逐个比较每一个元素是否与目标相同。
2.二分查找
二分查找又称折半查找,其思想是先将数组或列表按照大小顺序排好序,然后通过不断地折半缩小范围来寻找目标元素。
三、递归算法
递归算法是指在程序中调用自身的一种算法,其思想是将问题分解成更小的子问题,并不断地递归调用自身来解决这些子问题。
例如,计算阶乘可以使用递归算法来实现:
int factorial(int n)
{
if(n == 0 || n == 1)
return 1;
else
return n * factorial(n-1);
}
以上就是C语言中的简单算法,虽然它们看起来很简单,但是它们在实际编程中却有很大的作用。
掌握这些基本的、常用的、易于理解和实现的算法,可以提高我们编写程序的效率和质量。
C语言基本算法C语言是一门用于编写计算机程序的高级编程语言,其特点是语法简洁、表达力强,广泛应用于科学计算、系统开发等领域。
在C语言中,算法是解决问题的关键,因此掌握基本算法对于学习和使用C语言非常重要。
本文将介绍C语言中一些简单级别的基本算法。
1.顺序查找算法顺序查找算法是一种简单的算法,用于在一个无序数组中查找目标元素。
它的基本思想是逐个比较数组中的元素,如果找到目标元素则返回其索引,否则返回-12.二分查找算法二分查找算法是一种高效的算法,用于在一个有序数组中查找目标元素。
它的基本思想是将数组分成两半,判断目标元素在哪一半中,然后再在该半中进行查找,如此循环直到找到目标元素或确定不存在。
3.冒泡排序算法冒泡排序算法是一种简单的排序算法,用于将一个无序数组按照升序或降序排列。
它的基本思想是从数组的第一个元素开始,两两比较相邻元素的大小并交换位置,按照此规则不断遍历数组直到排序完成。
4.选择排序算法选择排序算法是一种简单的排序算法,用于将一个无序数组按照升序或降序排列。
它的基本思想是从数组中选择最小(或最大)的元素并放置到第一个位置,然后在剩余的元素中选择最小(或最大)的元素并放置到第二个位置,如此循环直到排序完成。
5.插入排序算法插入排序算法是一种简单的排序算法,用于将一个无序数组按照升序或降序排列。
它的基本思想是将数组分为已排序部分和未排序部分,每次从未排序部分选取一个元素插入到已排序部分的适当位置,如此循环直到排序完成。
6.计数排序算法计数排序算法是一种简单的排序算法,适用于待排序的元素是有限个数的情况。
它的基本思想是统计数组中每个元素出现的次数,然后根据统计结果重新排列数组。
7.求和算法求和算法是一种简单的计算算法,用于计算一个数组中所有元素的和。
它的基本思想是遍历数组,累加每个元素的值得到最终结果。
8.求平均值算法求平均值算法是一种简单的计算算法,用于计算一个数组中所有元素的平均值。
常见排序算法实现c语⾔常见排序算法代码实现c语⾔学习数据结构常见排序算法代码实现记录包括常见三⼤类排序算法实现选择排序:简单选择排序,堆排序插⼊排序:简单插⼊排序,希尔排序交换排序:冒泡排序,两端冒泡排序,快速排序归并排序基数排序代码如下#include<stdio.h>#include <stdbool.h>//交换函数void swap(int* a, int* b){int t;t = *a;*a = *b;*b = t;}//冒泡排序void bubblesort(int a[], int n){int i, j;bool flag;//循环n-1次for (i = 0; i < n - 1; i++){flag = false;//判断如果已经⽆逆序,跳过此次排序for (j = n - 1; j > i; j--)//从序列后⾯向前⾯冒泡{if (a[j - 1] > a[j]){swap(&a[j - 1], &a[j]);}flag = true;}if (flag == false) return;}}//两端冒泡法void doublebubblesort(int a[], int n){int low = 0, high = n - 1, i;bool flag = true;//判断此次排序是否需要循环while (low < high)//跳出循环条件{flag = false;for (i = low; i < high; i++)//从前往后冒泡{if (a[i] > a[i + 1]){swap(&a[i], &a[i + 1]);}flag = true;}high--;//以排好⼀个最⼤元素for (i = high; i > low; i--)//从后往前冒泡{if (a[i] < a[i - 1]){swap(&a[i], &a[i - 1]);}flag = true;}low++;//排好⼀个最⼩元素}}//插⼊排序void insertsort(int a[], int n){int temp;int i, j;for (i = 1; i < n; i++){temp = a[i];//记录for (j = i; j > 0 && a[j - 1] > temp; j--)//计算移动⼤⼩{a[j] = a[j - 1];//数组元素后移}a[j] = temp;//复制到插⼊位置}}//选择排序void choosesort(int a[], int n){int temp;int min;for (int i = 0; i < n - 1; i++){min = i;//初始化最⼩值位置for (int j = i + 1; j < n; j++)//依次⽐较⼤⼩{if (a[min] > a[j]){min = j;//更新最⼩值位置}}if (min != i)//如果最⼩值位置改变,则交换{swap(&a[i], &a[min]);}}}//希尔排序void shellsort(int a[], int n){int i, j, temp, dk;//相隔dk个距离for (dk = n / 2; dk >= 1; dk = dk / 2){//插⼊排序,将i从dk开始,每次与i-dk位置进⾏⽐较for (i = dk; i < n; i++){temp = a[i];for (j = i; j >= dk && a[j - dk] > temp; j -= dk){a[j] = a[j - dk];}a[j] = temp;//复制值到插⼊位置}}/*for(i=dk; i<n; i++){if(a[i]<a[i-dk]){temp=a[i];for(j=i-dk; j>0&&temp<a[j]; j-=dk){a[j+dk]=a[j];}a[j+dk]=temp;}*/}//快速排序,划分操作int partition(int a[], int left, int right){int pivot = a[left];//将表中第⼀个元素作为枢轴进⾏划分while (left < right)//循环跳出条件{//⽐枢轴⼩的元素移动到左端while (left < right && a[right] >= pivot){--right;//右端值⼤于枢轴则跳过,向左端继续寻找⼩于枢轴的值 }a[left] = a[right];//⽐枢轴⼤的元素移动到右端while (left < right && a[left] <= pivot){++left;//左端值⼩于枢轴则跳过,向右端继续寻找⼤于枢轴的值}a[right] = a[left];}a[left] = pivot;//枢轴存放到最终位置return left;//返回存放枢轴的最终位置}//递归调⽤快速排序void quick_sort(int a[], int left, int right){if (left < right)//跳出条件{int pivotpos = partition(a, left, right);//划分,得到枢轴位置quick_sort(a, left, pivotpos - 1);//对坐⼦表递归quick_sort(a, pivotpos + 1, right);//对友⼦表递归}}//快速排序封装接⼝void quicksort(int a[], int n){quick_sort(a, 0, n - 1);//调⽤}//调整堆函数//将n个元素数组中a[p]为根的⼦堆调整为最⼤堆void heapadjust(int a[], int p, int n){int parent, child, temp;temp = a[p];//暂存根结点的值for (parent = p; (parent * 2 + 1) < n; parent = child){child = parent * 2 + 1;if (child != n - 1 && a[child] < a[child + 1])//沿key较⼤的⼦结点向下筛选 {child++;//取parent较⼤的左右⼦结点}if (temp >= a[child]) break;//如果根结点⼤,找到合适位置筛选结束else{a[parent] = a[child];//下滤。
C语言经典算法大全精选1.排序算法1.1冒泡排序:通过不断交换相邻元素的位置,将最大(最小)值“冒泡”到序列的末尾(开头)。
1.2插入排序:将未排序的元素逐个插入已排序的序列中,保持序列始终有序。
1.3选择排序:每次从未排序的元素中选择最小(最大)的元素,放到已排序序列的末尾(开头)。
1.4快速排序:通过递归地将序列分割为较小和较大的两部分,然后分别对两部分进行排序。
1.5归并排序:将序列递归地分割为两个子序列,分别排序后再将结果合并。
1.6堆排序:构建最大(最小)堆,然后逐步将堆顶元素与最后一个元素交换,并调整堆结构。
2.查找算法2.1顺序查找:逐个比较元素,直到找到目标元素或遍历完整个序列。
2.2二分查找:在有序序列中,通过不断缩小查找范围,找到目标元素。
2.3插值查找:根据目标元素与序列中最大、最小元素的关系,按比例选择查找范围。
2.4哈希查找:利用哈希函数将目标元素映射到一个唯一的位置,从而快速定位目标元素。
3.字符串算法3.1字符串匹配算法:在文本串中查找给定的模式串,并返回匹配位置。
3.2字符串翻转:将一个字符串逆序输出。
3.3字符串压缩:将连续出现多次的字符压缩为一个字符,并输出压缩后的字符串。
3.4字符串拆分:按照指定的分隔符将字符串拆分为多个子串,并返回子串列表。
3.5字符串反转单词:将一个句子中的单词顺序逆序输出。
4.图算法4.1深度优先:从起始顶点出发,递归地访问所有能到达的未访问顶点。
4.2广度优先:从起始顶点出发,逐层地访问与当前层相邻的未访问顶点。
4.3最小生成树:找到连接所有顶点的具有最小权值的无环边集合。
4.4最短路径:找到两个顶点之间最短路径的权值和。
4.5拓扑排序:找到一个顶点的线性序列,满足所有有向边的起点在终点之前。
5.数学算法5.1质数判断:判断一个数是否为质数(只能被1和自身整除)。
5.2求最大公约数:找到两个数的最大公约数。
5.3求最小公倍数:找到两个数的最小公倍数。
c常用算法程序集C常用算法程序集一、排序算法排序算法是计算机科学中最基本、最常用的算法之一,常用于按照一定的规则将一组数据进行有序排列。
常见的排序算法有:冒泡排序、插入排序、选择排序、快速排序、归并排序等。
1. 冒泡排序:通过相邻元素的比较和交换来实现排序。
每一轮将最大的元素逐渐“冒泡”到末尾。
时间复杂度为O(n^2)。
2. 插入排序:将待排序的元素插入已排好序的部分,从而达到排序的目的。
时间复杂度为O(n^2),但在部分有序的情况下表现较好。
3. 选择排序:每一轮从待排序的元素中选出最小(或最大)的元素放到已排序的末尾。
时间复杂度为O(n^2),性能较差。
4. 快速排序:通过一趟排序将待排序的序列分割成两部分,其中一部分的所有元素都比另一部分小。
再分别对两部分进行排序,递归地进行下去。
时间复杂度为O(nlogn),性能较好。
5. 归并排序:将待排序的序列分成若干个子序列,分别进行排序,然后再将排好序的子序列合并。
时间复杂度为O(nlogn),稳定且效率较高。
二、查找算法查找算法是在给定的数据集中寻找特定元素的过程,常用于在大规模数据中快速定位目标元素。
常见的查找算法有:顺序查找、二分查找、哈希查找等。
1. 顺序查找:逐个遍历待查找的元素,直到找到目标元素或遍历完整个数据集。
时间复杂度为O(n),适用于小规模数据集。
2. 二分查找:在有序的数据集中,将目标元素与中间元素进行比较,缩小查找范围,直到找到目标元素或范围为空。
时间复杂度为O(logn),适用于大规模数据集。
3. 哈希查找:利用哈希函数将元素映射到一个确定的位置,通过该位置快速查找目标元素。
时间复杂度为O(1),但需要额外的空间存储哈希表。
三、图算法图算法用于解决图论中的问题,常用于描述事物之间的关系和网络结构。
常见的图算法有:深度优先搜索(DFS)、广度优先搜索(BFS)、最短路径算法(Dijkstra算法、Floyd-Warshall算法)等。
常见的C语言排序算法有以下几种:
1. 冒泡排序(Bubble Sort):比较相邻的元素,如果前一个元素大于后一个元素,则交换它们的位置,重复这个过程直到整个序列有序。
2. 插入排序(Insertion Sort):将未排序的元素逐个插入到已排序序列中的正确位置,直到整个序列有序。
3. 选择排序(Selection Sort):每次从未排序的元素中选择最小的元素,将其放到已排序序列的末尾,重复这个过程直到整个序列有序。
4. 快速排序(Quick Sort):选择一个基准元素,将序列分成两部分,一部分小于等于基准元素,一部分大于基准元素,然后对两部分递归地进行快速排序。
5. 归并排序(Merge Sort):将序列分成两部分,分别对两部分进行归并排序,然后将两个有序的子序列合并成一个有序的序列。
6. 堆排序(Heap Sort):将序列构建成一个最大堆,然后将堆顶元素与堆末尾元素交换,重复这个过程直到整个序列有序。
7. 希尔排序(Shell Sort):将序列按照一定的间隔分成若干个子序列,对每个子序列进行插入排序,然后逐渐减小间隔直到间隔为1,最后对整个序列进行插入排序。
8. 计数排序(Counting Sort):统计序列中每个元素出现的次数,然后按照元素的大小顺序将它们放入一个新的序列中。
9. 基数排序(Radix Sort):按照元素的个位、十位、百位等依次进行排序,直到所有位数都排完为止。
以上是常见的C语言排序算法,每种算法都有其特点和适用场景,选择合适的排序算法可以提高排序效率。
C语言常用9种算法C语言是一门广泛应用于编程领域的语言,具有丰富的算法库和功能。
在C语言中,有许多常用的算法可以帮助程序员解决各种问题。
本文将介绍C语言中常用的9种算法,以帮助读者深入了解和应用这些算法。
1.顺序算法:顺序算法是一种简单但有效的方法,通过逐个比较目标元素和数组中的元素来寻找指定值。
该算法适用于小规模的数据集,时间复杂度为O(n)。
2.二分算法:二分算法是一种高效的方法,适用于已排序的数组。
该算法通过将目标值与数组的中间元素进行比较,并根据比较结果将范围缩小一半。
时间复杂度为O(log n)。
3.冒泡排序算法:冒泡排序算法是一种简单但低效的排序方法,通过反复交换相邻的元素将较大的元素逐渐移至数组的末尾。
时间复杂度为O(n^2)。
4.选择排序算法:选择排序算法是一种简单但较为高效的排序方法,通过找到最小元素并将其放置在数组的起始位置,逐个选择剩余元素中的最小值,直到完成排序。
时间复杂度为O(n^2)。
5.插入排序算法:插入排序算法是一种简单而且对小数据集很有效的排序方法,通过将未排序的元素依次插入已排序的序列中,逐步构建有序的序列。
时间复杂度为O(n^2)。
6.快速排序算法:快速排序算法是一种高效的排序方法,通过选择一个基准值将数组分割成两个子数组,较小的值放在基准值的左边,较大的值放在右边。
然后对子数组进行递归排序。
时间复杂度为O(n log n)。
7.归并排序算法:归并排序算法是一种稳定而且高效的排序方法,通过将数组递归地分成两个子数组,然后合并这些子数组以得到排序结果。
时间复杂度为O(n log n)。
8.哈希算法:哈希算法是一种用于将数据映射到特定位置的算法,可以快速访问数据。
C语言提供了多种哈希算法库,例如MD5和SHA1等,用于数据完整性校验和密码存储等应用场景。
9.图算法:图算法是一类用于处理图结构的算法,包括广度优先、深度优先和最短路径算法等。
通过这些算法,可以实现许多图相关的问题,如寻找社交网络中的最短路径或者查找网络拓扑结构等。
C语言三种基本排序方法
一、选择排序法。
选择排序法的第一层循环从起始元素开始选到倒数第二个元素,主要是在每次进入的第二层循环之前,将外层循环的下标赋值给临时变量,接下来的第二层循环中,如果发现有比这个最小位置处的元素更小的元素,则将那个更小的元素的下标赋给临时变量,最后,在二层循环退出后,如果临时变量改变,则说明,有比当前外层循环位置更小的元素,需要将这两个元素交换。
二、冒泡排序法。
冒泡排序算法的运作如下:(从后往前)比较相邻的元素。
如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
三、插入排序法。
所谓插入排序法,就是检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就可以停止了。
插入排序法主要的回圈有两个变数:i和j,每一次执行这个回圈,就会将第i个数字放到左边恰当的位置去。
插入排序的基本思想是:每步将一个待排序的纪录,按其关
键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止(分为直接插入法和折半插入法)。
c语言常用算法总结
C语言是一种通用、高级计算机编程语言,也是应用最广泛的编程语言之一。
C语言以简洁、高效、迅捷而著称。
在C语言中,算法是编程的基础,因此我们需要学习一些常见的C语言算法。
1. 冒泡排序算法
冒泡排序算法是最简单的排序算法。
它通过交换相邻两数,将小数不断“冒泡”到左边,大数“沉降”到右边,最终使整个序列排序。
插入排序算法是将一个元素插入到有序列表中的适当位置。
插入排序算法可以逐步地将目标元素插入到已排序列表中,最终达到有序列表。
快速排序算法是最常用的排序算法之一。
快速排序算法通过递归地划分数组,把比key小的元素放入数组左边,比key大的元素放入数组右边。
最终达到有序列表。
归并排序算法将待排序的数组递归划分为若干个子数组,并将这些子数组排序合并为一个大的有序数组。
希尔排序算法是一种基于插入排序的高效排序算法。
它通过一个增量序列,将待排序数组分成若干个子数组,然后对每个子数组进行插入排序,最终达到有序列表。
堆排序算法是一种基于树形数据结构的高效排序算法。
它通过将待排序数组构建成一个大根堆,然后将根节点(最大值)与最后一个节点交换位置,然后再次构建大根堆,重复进行此操作,最终达到有序列表。
基数排序算法是一种基于数字位的排序算法。
基数排序算法先按照数字位进行排序,然后按照高位到低位的顺序逐步进行排序,最终得到有序列表。
10. 斐波那契数列算法
斐波那契数列算法是一个递推算法,斐波那契数组是由0和1开始,后面每一个数都等于前面两个数之和。
这个算法通常用于解决优化问题,如最优解和最优值等问题。
1.冒泡排序:
2.简单选择排序:
3.快速排序:
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
4.直接插入排序:
5.折半插入排序:
折半插入排序(binary insertion sort)是对插入排序算法的一种改进,在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为
a[high],则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。
代码:
6.希尔排序:。
C语言9种常用排序法1.冒泡排序2.选择排序3.插入排序4.快速排序5.希尔排序6.归并排序7.堆排序8.带哨兵的直接插入排序9.基数排序例子:乱序输入n个数,输出从小到大排序后的结果1.冒泡排序#include<stdio.h>int main(){int i, j, n, a[100], temp;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n-1;i++) //总共需冒泡n-1次{for(j=0;j<n-i-1;j++) //第i趟冒泡{if(a[j]>a[j+1]) //比较a[j]与a[j+1],使a[j+1]大于a[j] {temp = a[j+1];a[j+1] = a[j];a[j] = temp;}}}for(i=0;i<n;i++) //打印printf("%d ",a[i]);printf("\n");}return 0;}2.选择排序#include<stdio.h>int main(){int i, j, n, a[100], t, temp;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n-1;i++) //总共排序n-1趟{t = i;for(j=i+1;j<n;j++) //第i趟从a[i+1]~a[n-1]中选最小的数与a[i]交换 {if(a[t]>a[j])t = j;}temp = a[i];a[i] = a[t];a[t] = temp;}for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}return 0;}3.快速排序/*1.假设数组为a[n];2.第一次排序过程如下:取x = 0 ( a[0]为中轴 );i=0 (第一个元素下标), j=n-1(最后一个元素下标);重复下面过程:(直到i>=j){从a[j]起,向前找小于a[x]的元素,同时j--,找到后,a[j]与a[x]交换,x=j;从a[i]起,向后找大于a[x]的元素,同时i++,找到后,a[i]与a[x]交换,x=i; }3.注意快排函数是迭代函数,必须要有结束条件 (因为忽略结束条件,调试了很久......)4.再对a[low]~a[x-1]、a[x+1]~a[high]分别调用快排函数*/#include<stdio.h>void quicksort(int a[],int low,int high);int main(){int i, n, a[100];while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);quicksort(a,0,n-1);for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}return 0;}void quicksort(int a[],int low,int high){if(low>=high) return; //坑爹的结束条件,return后面不能跟数值 int i=low, j= high, x=i, temp;while(i<j){for(;a[j]>=a[x]&&i<j;j--);if(i<j){temp = a[j];a[j] = a[i];a[i] = temp;x = j;i++;}elsebreak; //i>=j即可跳出本次while循环for(;a[i]<=a[x]&&i<j;i++);if(i<j){temp = a[i];a[j] = temp;x = i;j--;}elsebreak; //跳出本次while循环 }quicksort(a,low,x-1);quicksort(a,x+1,high);}4.插入排序法#include<stdio.h>void show(int a[],int n) //输出数组{int i;for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}void insertsort(int a[],int n);int main(){while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);insertsort(a,n);show(a,n);}return 0;}void insertsort(int a[],int n){int i ,j ,k ,temp;for(i=1;i<n;i++) //插入a[i]{j=i-1;for(;a[i]<a[j]&&j>=0;j--); //寻找插入点j++;if(j==i) //该数有序,不需要前插continue;else{temp=a[i];for(k=i-1;k>=j;k--) //将插入点后面的数依次后移一位 {a[k+1]=a[k];}}}}5.shell排序法#include<stdio.h>void show(int a[],int n) //输出数组{int i;for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}void shellsort(int a[],int n);int main(){int i, n, a[100];while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);shellsort(a,n);show(a,n);}return 0;}void shellsort(int a[],int n){int k ,i ,j ,l ,temp;k = n/2;while(k>=1){for(i=k;i<n;i++){if(a[i]>=a[i-k]) //已经有序,不需要移动continue;else{for(j=i-k;a[j]>=a[i]&&j>=0;j=j-k); j+=k; //寻找插入点a[j] temp = a[i]; // 保存a[i]for(l=i-k;l>=j;l-=k) //依次向后移动k个位置{a[l+k] = a[l];}a[j]=temp; //插入}}k = k/2;}}6.归并排序归并排序是一种很容易进行并行化的算法,因为归并的各个数据区间都是独立的,没有依赖关系。
转至【程序员笔试知识点整理】排序方法分类有:插入、选择、交换、归并、计数等五种排序方法。
(1)插入排序中又可分为:直接插入、折半插入、2路插入(?)、希尔排序。
这几种插入排序算法的最根本的不同点,说到底就是根据什么规则寻找新元素的插入点。
直接插入是依次寻找,折半插入是折半寻找,希尔排序,是通过控制每次参与排序的数的总范围“由小到大”的增量来实现排序效率提高的目的。
(2)交换排序,又称冒泡排序,在交换排序的基础上改进又可以得到快速排序。
快速排序的思想,一语以敝之:用中间数将待排数据组一分为二。
(3)选择排序可以分为:简单选择、树选择、堆排序。
选择排序相对于前面几种排序算法来说,难度大一点。
这三种方法的不同点是,根据什么规则选取最小的数。
简单选择,是通过简单的数组遍历方案确定最小数;树选择,是通过“锦标赛”类似的思想,让两数相比,不断淘汰较大(小)者,最终选出最小(大)数;而堆排序,是利用堆这种数据结构的性质,通过堆元素的删除、调整等一系列操作将最小数选出放在堆顶。
堆排序中的堆建立、堆调整是重要考点。
(4)归并排序,是通过“归并”这种操作完成排序的目的,既然是归并就必须是两者以上的数据集合才可能实现归并。
所以,在归并排序中,关注最多的就是2路归并。
算法思想比较简单,有一点,要铭记在心:归并排序是稳定排序。
(5)基数排序,是一种很特别的排序方法,也正是由于它的特殊,所以,基数排序就比较适合于一些特别的场合,比如扑克牌排序问题等。
基数排序,又分为两种:多关键字的排序(扑克牌排序),链式排序(整数排序)。
基数排序的核心思想也是利用“基数空间”这个概念将问题规模规范、变小,并且,在排序的过程中,只要按照基排的思想,是不用进行关键字比较的,这样得出的最终序列就是一个有序序列。
本章各种排序算法的思想以及伪代码实现,及其时间复杂度都是必须掌握的。
//////////////////////////////////////////////稳定性分析////////////////////////////////////////////////排序算法的稳定性,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。
常见经典排序算法(C语言)1.希尔排序2.二分插入法3.直接插入法4.带哨兵的直接排序法5.冒泡排序6.选择排序7.快速排序8.堆排序一.希尔(Shell)排序法(又称宿小增量排序,是1959年由D.L.Shell提出来的)/* Shell 排序法*/#include <stdio.h>void sort(int v[],int n){int gap,i,j,temp;for(gap=n/2;gap>0;gap /= 2) /* 设置排序的步长,步长gap每次减半,直到减到1 */ {for(i=gap;i<n;i++) /* 定位到每一个元素*/{for(j=i-gap;(j >= 0) && (v[j] > v[j+gap]);j -= gap ) /* 比较相距gap远的两个元素的大小,根据排序方向决定如何调换*/{temp=v[j];v[j]=v[j+gap];v[j+gap]=temp;}}}}二.二分插入法/* 二分插入法*/void HalfInsertSort(int a[], int len){int i, j,temp;int low, high, mid;for (i=1; i<len; i++){temp = a[i];/* 保存但前元素*/low = 0;high = i-1;while (low <= high) /* 在a[low...high]中折半查找有序插入的位置*/{mid = (low + high) / 2; /* 找到中间元素*/if (a[mid] > temp) /* 如果中间元素比但前元素大,当前元素要插入到中间元素的左侧*/{high = mid-1;}else /* 如果中间元素比当前元素小,但前元素要插入到中间元素的右侧*/{low = mid+1;}} /* 找到当前元素的位置,在low和high之间*/for (j=i-1; j>high; j--)/* 元素后移*/{a[j+1] = a[j];}a[high+1] = temp; /* 插入*/}}三.直接插入法/*直接插入法*/void InsertionSort(int input[],int len){int i,j,temp;for (i = 1; i < len; i++){temp = input[i]; /* 操作当前元素,先保存在其它变量中*/for (j = i - 1;j>-1&&input[j] > temp ; j--) /* 从当前元素的上一个元素开始查找合适的位置*/{input[j + 1] = input[j]; /* 一边找一边移动元素*/input[j] = temp;}}}四.带哨兵的直接排序法/*** 带哨兵的直接插入排序,数组的第一个元素不用于存储有效数据* 将input[0]作为哨兵,可以避免判定input[j]中,数组是否越界* 因为在j--的过程中,当j减小到0时,变成了input[0]与input[0]* 自身进行比较,很明显这个时候说明位置i之前的数字都比input[i]小* 位置i上的数字不需要移动,直接进入下一轮的插入比较。
**/void InsertionSortWithPiquet(int input[],int len){int i,j;for (i = 2; i < len; i++) /* 保证数组input第一元素的存储数据无效,从第二个数据开始与它前面的元素比较*/{input[0] = input[i];for (j = i - 1; input[j] > input[0] ; j--){input[j + 1] = input[j];input[j] = input[0]; /* input[j]一直都是排序的元素中最大的那一个*/ }}}五.冒泡法/* 冒泡排序法*/void Bublesort(int a[],int n){int i,j,k;for(j=0;j<n;j++) /* 气泡法要排序n次*/{for(i=0;i<n-j;i++) /* 值比较大的元素沉下去后,只把剩下的元素中的最大值再沉下去就可以啦*/{if(a[i]>a[i+1]) /* 把值比较大的元素沉到底*/{k=a[i];a[i]=a[i+1];a[i+1]=k;}}}}六.选择排序法/*算法原理:首先以一个元素为基准,从一个方向开始扫描,* 比如从左至右扫描,以A[0]为基准。
接下来从A[0]...A[9]* 中找出最小的元素,将其与A[0]交换。
然后将基准位置右* 移一位,重复上面的动作,比如,以A[1]为基准,找出* A[1]~A[9]中最小的,将其与A[1]交换。
一直进行到基准位* 置移到数组最后一个元素时排序结束(此时基准左边所有元素* 均递增有序,而基准为最后一个元素,故完成排序)。
*/void Selectsort(int A[],int n){int i,j,min,temp;for(i=0;i<n;i++){min=i;for(j=i+1;j<=n;j++) /* 从j往前的数据都是排好的,所以从j开始往下找剩下的元素中最小的*/{if(A[min]>A[j]) /* 把剩下元素中最小的那个放到A[i]中*/{temp=A[i];A[i]=A[j];A[j]=temp;}}}}七.快速排序/* 快速排序(quick sort)。
在这种方法中,* n 个元素被分成三段(组):左段left,* 右段right和中段middle。
中段* 仅包含一个元素。
左段中各元素都小于等* 于中段元素,右段中各元素都大于等于中* 段元素。
因此left和right中的元* 素可以独立排序,并且不必对left和* right的排序结果进行合并。
* 使用快速排序方法对a[0:n-1]排序* 从a[0:n-1]中选择一个元素作为middle,* 该元素为支点把余下的元素分割为两段left* 和right,使得left中的元素都小于* 等于支点,而right 中的元素都大于等于支点* 递归地使用快速排序方法对left 进行排序* 递归地使用快速排序方法对right 进行排序* 所得结果为left+middle+right*/void Quick_sort(int data[],int low,int high){int mid;if(low<high){mid=Partition(data,low,high);Quick_sort(data,low,mid-1); /* 递归调用*/Quick_sort(data,mid+1,high);}}/* 要注意看清楚下面的数据之间是如何替换的,* 首先选一个中间值,就是第一个元素data[low],* 然后从该元素的最右侧开始找到比它小的元素,把* 该元素复制到它中间值原来的位置(data[low]=data[high]),* 然后从该元素的最左侧开始找到比它大的元素,把* 该元素复制到上边刚刚找到的那个元素的位置(data[high]=data[low]),* 最后将这个刚空出来的位置装入中间值(data[low]=data[0]),* 这样一来比mid大的都会跑到mid的右侧,小于mid的会在左侧,* 最后一行,返回的low是中间元素的位置,左右分别递归就可以排好序了。
*/int Partition(int data[],int low,int high){int mid;data[0]=data[low];mid=data[low];while(low < high){while((low < high) && (data[high] >= mid)){--high;}data[low]=data[high]; /* 从high的位置开始往low的方向找,找到比data[low]小的元素,存到data[low]中*/while((low < high) && (data[low] < mid)) /* 新得到的data[low]肯定小于原来的data[low]即mid */{++low;}data[high]=data[low]; /* 从low的位置开始往high的方向找,找到比data[high]大的元素,存在data[high]中*/}data[low]=data[0]; /* 把low的新位置存上原来的data[low]的数据*/return low; /* 递归时,把它做为右侧元素的low */}八.堆排序/*************************************************************** 堆的定义n 个元素的序列{k1,k2,...,kn}当且仅当满足下列关系时,* 称为堆:* ki<=k2i ki<=k2i+1 (i=1,2,...,n/2)* 或* ki>=k2i ki>=k2i+1 (i=1,2,...,n/2)* 堆排序思路:* 建立在树形选择排序基础上;* 将待排序列建成堆(初始堆生成)后,序列的第一个元素(堆顶元素)就一定是序列中的最大元素;* 将其与序列的最后一个元素交换,将序列长度减一;* 再将序列建成堆(堆调整)后,堆顶元素仍是序列中的最大元素,再次将其与序列最后一个元素交换并缩短序列长度;* 反复此过程,直至序列长度为一,所得序列即为排序后结果。
**************************************************************/void HeapAdjust(int data[],int s,int m) /* 排列成堆的形式*/{int j,rc;rc=data[s]; /* 保存处理元素*/for(j=2*s;j<=m;j*=2) /* 处理父亲元素*/{if(j<m && data[j]<data[j+1]) ++j; /* 取较大的孩子节点*/if(rc>data[j]) break;data[s]=data[j]; /* 父节点比较大的孩子节点大则互换,保证父节点比所有子节点都大(父节点存储在前面)*/s=j;}data[s]=rc; /* 相当于data[j]=rc */}void Heap_sort(int data[],int long_n) /* 堆排序函数*/{int i,temp;for(i=long_n/2;i>0;--i) /* 还没有读懂这样处理的原因,希望大家不吝赐教*/{HeapAdjust(data,i,long_n); /* 处理后,data[i]是这个数组后半部分的最大值*/}for(i=long_n;i>0;--i){temp=data[1]; /* 把根元素(剩下元素中最大的那个)放到结尾,下一次只要排剩下的数就可以啦*/data[1]=data[i];data[i]=temp;HeapAdjust(data,1,i-1);}}每个算法有什么优缺点,可以参照百度文库地址:/view/c3054c0f7cd184254b353516.html本文转载:/wengwuzi/archive/2008/10/05/3017968.aspx。