C语言实现九大排序算法的实例代码

直接插入排序

将数组分为两个部分,一个是有序部分,一个是无序部分。从无序部分中依次取出元素插入到有序部分中。过程就是遍历有序部分,实现起来比较简单。

#include <stdio.h>

void insertion_sort(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  int data = arr[i];
  int j = 0;
  while (arr[j] < arr[i]) {
   j++;
  }
  for (int k = i; k >= j + 1; k--) {
   arr[k] = arr[k - 1];
  }
  arr[j] = data;
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int arr[7] = {8, 2, 6, 0, 5, 7, 4};
 insertion_sort(arr, 7);
 print_array(arr, 7);
 return 0;
}

折半插入排序

折半插入再直接插入上有改进,用折半搜索替换遍历数组,在数组长度大时能够提升查找性能。其本质还是从无序部分取出元素插入到有序部分中。

#include <stdio.h>

void binary_insertion_sort(int arr[], int array_length) {
 int i, j, low = 0, high = 0, mid;
 int temp = 0;
 for (i = 1; i < array_length; i++) {
  low = 0;
  high = i - 1;
  temp = arr[i];
  while (low <= high) {
   mid = (low + high) / 2;
   if (arr[mid] > temp) {
    high = mid - 1;
   } else {
    low = mid + 1;
   }
  }
  for (j = i; j > low; j--) {
   arr[j] = arr[j - 1];
  }
  arr[low] = temp;
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int brr[5] = {2, 6, 0, 5, 7};
 binary_insertion_sort(brr, 5);
 print_array(brr, 5);
 return 0;
}

希尔排序

希尔排序的核心就是根据步长分组,组内进行插入排序。关于步长的选取,第一次步长取元素的个数,后面每次取原来步长的一半。

希尔排序属于插入排序的一种。

#include <stdio.h>

void shell_sort(int arr[], int array_length) {
 int step = array_length / 2;
 while (step >= 1) {
  for (int i = 0; i < array_length; i += step) {
   int data = arr[i];
   int j = 0;
   while (arr[j] < arr[i]) {
    j++;
   }
   for (int k = i; k >= j + 1; k--) {
    arr[k] = arr[k - 1];
   }
   arr[j] = data;
  }
  step = step / 2;
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int crr[10] = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81};
 shell_sort(crr, 10);
 print_array(crr, 10);
 return 0;
}

冒泡排序

冒泡的特点是两两交换。通过交换把最大的元素交换到后面去了,每次循环遍历都把无序部分最大的“沉”到后面去。小数上“浮”和大数下“沉”其实没有差别,都能实现冒泡。

#include <stdio.h>

void bubble_sort(int arr[], int array_length) {
 for (int i = 0; i < array_length - 1; ++i) {
  for (int j = 0; j < array_length - i - 1; ++j) {
   if (arr[j] > arr[j + 1]) {
    int temp = arr[j];
    arr[j] = arr[j + 1];
    arr[j + 1] = temp;
   }
  }
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int drr[7] = {8, 2, 6, 0, 5, 7, 4};
 bubble_sort(drr, 7);
 print_array(drr, 7);
 return 0;
}

快速排序

快排的精髓在于选定一个标准(通常选数组的第一个元素),然后将所有元素根据标准分为小于和大于两个部分,然后这两个部分再选取标准,继续递归下去,不难想象最终排序结果是整体有序的。

#include <stdio.h>

int getStandard(int arr[], int low, int high) {
 int flag = arr[low];
 while (low < high) {
  while (low < high && arr[high] >= flag) {
   high--;
  }
  if (low < high) {
   arr[low] = arr[high];
  }
  while (low < high && arr[low] <= flag) {
   low++;
  }
  if (low < high) {
   arr[high] = arr[low];
  }
 }
 arr[low] = flag;
 return low;
}

void quick_sort(int arr[], int low, int high) {
 if (low < high) {
  int pos = getStandard(arr, low, high);
  quick_sort(arr, low, pos - 1);
  quick_sort(arr, pos + 1, high);
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int err[10] = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81};
 quick_sort(err, 0, 9);
 print_array(err, 10);
 return 0;
}

直接选择排序

如其名,直接选择一个最小的放到最前面,但是遍历往往导致效率较低。

#include <stdio.h>

void select_sort(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  int min_pos = i;
  for (int j = i; j < array_length; ++j) {
   if (arr[min_pos] > arr[j])
    min_pos = j;
  }
  int temp = arr[min_pos];
  arr[min_pos] = arr[i];
  arr[i] = temp;
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int frr[7] = {8, 2, 6, 0, 5, 7, 4};
 select_sort(frr, 7);
 print_array(frr, 7);
 return 0;
}

堆排序

将数组转换为一颗完全二叉树。任意一个父节点大于它的子节点,这样的完全二叉树叫做大顶堆;与之相反的,任意一个父节点小于它的子节点,这样的完全二叉树叫做小顶堆。

堆排序的精华就在于把元素个数为n的完全二叉树转换为大顶堆,然后把堆顶和最后一个元素交换,此时产生了一个元素个数为n-1的完全二叉树,然后再转换为大顶堆,继续把堆顶和最后一个元素交换。循环往复就实现了排序。其实质还是选择排序,每次选出一个最大的,和最后一个交换,不过完全二叉树中选最大元素比遍历数组会快很多。

#include <stdio.h>

void heap_adjust(int arr[], int n) {
 for (int i = n / 2; i >= 1; i--) {
  if (arr[i - 1] < arr[2 * i - 1]) {
   int temp = arr[i - 1];
   arr[i - 1] = arr[2 * i - 1];
   arr[2 * i - 1] = temp;
  }
  if (arr[i - 1] < arr[2 * i] && (2 * i) < n) {
   int temp = arr[i - 1];
   arr[i - 1] = arr[2 * i];
   arr[2 * i] = temp;
  }
 }
}

void heap_sort(int arr[], int array_length) {
 int n = array_length;
 do {
  heap_adjust(arr, n);
  int temp = arr[0];
  arr[0] = arr[n - 1];
  arr[n - 1] = temp;
 } while (n--);
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int grr[7] = {8, 2, 6, 0, 5, 7, 4};
 heap_sort(grr, 7);
 print_array(grr, 7);
 return 0;
}

归并排序

归并的思想在于对复杂问题的分治,打散到最小长度后然后再进行合并操作。假设有两个数组A、B,指针i指向A的头部,指针j指向B的头部,两边同时进行遍历,找到一个小的就放到数组里面,对应指针后移一位,这样就能够保证合并后的数组是有序的。

#include <stdio.h>
#include <malloc.h>

void merge(int arr[], int start, int mid, int end) {
 int *new_array = (int *) malloc(sizeof(int) * (end - start + 1));
 int i = start;
 int j = mid + 1;
 int k = 0;
 while (i <= mid && j <= end) {
  if (arr[i] < arr[j]) {
   new_array[k++] = arr[i++];
  } else {
   new_array[k++] = arr[j++];
  }
 }
 while (i <= mid) {
  new_array[k++] = arr[i++];
 }
 while (j <= end) {
  new_array[k++] = arr[j++];
 }
 for (int l = 0; l < k; ++l) {
  arr[start + l] = new_array[l];
 }
 free(new_array);
}

void merge_sort(int arr[], int start, int end) {
 int mid = (start + end) / 2;
 if (start >= end) {
  return;
 }
 merge_sort(arr, start, mid);
 merge_sort(arr, mid + 1, end);
 merge(arr, start, mid, end);
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int hrr[10] = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81};
 merge_sort(hrr, 0, 9);
 print_array(hrr, 10);
 return 0;
}

基数排序

先按照个位排序将所有数字分配到0-9这10个桶里面,然后再按照桶的顺序收集起来;再按照十位排序,同样的步骤……

基础排序的本质是对每一位进行排序,对每一位进行排序后就能保证这一个数整体的大小是按照顺序排列的。

#include <stdio.h>
#include <malloc.h>

int get_num(int number, int pos) {
 int num = 0;
 while (pos--) {
  num = number % 10;
  number = number / 10;
 }
 return num;
}

void radix_sort(int arr[], int array_length) {
 int *bucket[10];
 for (int i = 0; i < 10; ++i) {
  bucket[i] = (int *) malloc(sizeof(int) * array_length + 1);
  bucket[i][0] = 0;//桶的第一位保存桶中元素个数
 }
 for (int b = 1; b <= 31; ++b) {
  for (int i = 0; i < array_length; ++i) {
   int num = get_num(arr[i], b);//计算每个位上的数字(个位、十位、百位...)
   int index = ++bucket[num][0];//计算下标
   bucket[num][index] = arr[i];//保存到桶中
  }
  for (int i = 0, k = 0; i < 10; i++) {
   for (int j = 1; j <= bucket[i][0]; ++j) {
    arr[k++] = bucket[i][j];//从桶里面按顺序取出来
   }
   bucket[i][0] = 0;//下标清零
  }
 }
}

void print_array(int arr[], int array_length) {
 for (int i = 0; i < array_length; ++i) {
  printf("%d ", arr[i]);
 }
 printf("\n");
}

int main() {
 int irr[10] = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81};
 radix_sort(irr, 10);
 print_array(irr, 10);
 return 0;
}

总结

到此这篇关于C语言实现九大排序算法的文章就介绍到这了,更多相关C语言九大排序算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 必须知道的C语言八大排序算法(收藏)

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1.插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到

  • C语言实现快速排序算法

    一.快速排序算法(Quicksort) 1. 定义 快速排序由C. A. R. Hoare在1962年提出.快速排序是对冒泡排序的一种改进,采用了一种分治的策略. 2. 基本思想 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 3. 步骤 a. 先从数列中取出一个数作为基准数. b. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全

  • C语言实现排序算法之归并排序详解

    排序算法中的归并排序(Merge Sort)是利用"归并"技术来进行排序.归并是指将若干个已排序的子文件合并成一个有序的文件. 一.实现原理: 1.算法基本思路 设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中. (1)合并过程 合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置.合并时依次比较R[i

  • 希尔排序算法的C语言实现示例

    希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位 希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能.这样可以让一个元素可以一次性地朝最终位置前进一大步.然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几

  • C语言排序算法之插入排序

    算法实现: 使用插入排序将下面的数字按照从小到大的顺序排列 步骤1:数组中已经排好的是{1},将9插入数组中 步骤2:数组中已经排好的是{2,9},将5插入数组中 步骤3:数组中已经排好的是{2,5,9},将4插入数组中 步骤4:数组中已经排好的是{2,4,,5,9},将8插入数组中 步骤5:数组中已经排好的是{2,4,,5,8,9},将1插入数组中 步骤6:数组中已经排好的是{1,2,4,,5,8,9},将6插入数组中 步骤7:排序完成 程序代码: #include <stdio.h> #i

  • C语言实现基于最大堆和最小堆的堆排序算法示例

    堆定义 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i]<=key[2i+2](小顶堆)或者:Key[i]>=Key[2i+1]&&key>=key[2i+2](大顶堆) 即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字. 堆排序的思想 利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单. 最大堆:所有节点的子节点比其

  • c语言实现奇偶排序算法

    =====第2题:奇偶排序(一)===== 总时间限制:1000ms内存限制:65536kB描述输入十个整数,将十个整数按升序排列输出,并且奇数在前,偶数在后.输入输入十个整数输出按照奇偶排序好的十个整数 复制代码 代码如下: #include<stdio.h> #define  COUNT 10#define bool int#define true 1#define false 0 /*****负责冒泡排序***/int* sortFunction(int data[]){ int i,j

  • c语言快速排序算法示例代码分享

    步骤为:1.从数列中挑出一个元素,称为 "基准"(pivot);2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在这个分区退出之后,该基准就处于数列的中间位置.这个称为分区(partition)操作.3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序.递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了.虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iterat

  • C语言对堆排序一个算法思路和实现代码

    算法思想简单描述: 堆排序是一种树形选择排序,是对直接选择排序的有效改进. 堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆.在这里只讨论满足前者条件的堆. 由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项.完全二叉树可以很直观地表示堆的结构.堆顶为根,其它为左子树.右子树. 初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的

  • c语言实现冒泡排序、希尔排序等多种算法示例

    实现以下排序 插入排序O(n^2) 冒泡排序 O(n^2) 选择排序 O(n^2) 快速排序 O(n log n) 堆排序 O(n log n) 归并排序 O(n log n) 希尔排序 O(n^1.25) 1.插入排序 O(n^2) 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下:⒈ 从第一个元素开始,该元素可以认为已经被排序⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置⒋ 重复步骤3,直到找到已排序的元素

随机推荐