算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版
2015-11-21 17:26
1211 查看
每次开始动手写算法,都是先把插入排序,冒泡排序写一遍,十次有九次是重复的,所以这次下定决心,将所有常规的排序算法写了一遍,以便日后熟悉。
以下代码总用一个main函数和一个自定义的CommonFunction函数
CommonFunction函数中定义了一个交换函数和一个输出函数:
main函数:
1、冒泡排序:
2、选择排序算法:
3、插入排序算法:
4、希尔排序算法:
5、快速排序算法:
6堆排序算法:
7、归并排序算法:
最后的结果是:
以下代码总用一个main函数和一个自定义的CommonFunction函数
CommonFunction函数中定义了一个交换函数和一个输出函数:
/* * CommonFunction.h * * Created on: 2015年11月16日 * Author: hoojjack */ #pragma once namespace section4 { void swap(int *first, int *second) { int temp; temp = *first; *first = *second; *second = temp; } void printfByStep(int *a, int i, int len) { int k; printf("The result of the %dth step\n", i); for (k = 0; k < len; k++) printf("%d ", a[k]); printf("\n"); } }
main函数:
/* * SortMain.cpp * * Created on: 2015年11月16日 * Author: hoojjack */ #include<stdio.h> #include<stdlib.h> #include<time.h> #include<sys/timeb.h> #include "BubbleSort.h" #include "SelectionSort.h" #include "InsertionSort.h" #include "ShellSort.h" #include "QuickSort.h" #include "CommonFunction.h" #include "HeapSort.h" #include "MergeSort.h" #define SIZE 10 int main() { int array[SIZE], i, options; srand(time(NULL)); for (i = 0; i < SIZE; i++) { array[i] = rand() / 1000 + 10; } printf("The array of original sorting\n"); for (i = 0; i < SIZE; i++) { printf("%d ", array[i]); } printf("\nPlease choose your options:\n 1:BubbleSort\t 2:Selection\t "); printf( "3:InsertSort\t 4:ShellSort\t 5:QuickSort\t 6:HeapSort\t 7:MergeSort\t\n"); // scanf("%d", &options); for (i = 1; i <= 7; i++) { options=i; switch (options) { case 1: printf("The result of Bubble sorting is following:\n"); section4::bubbleSort(array, SIZE); break; case 2: printf("The result of Selection sorting is following:\n"); section4::selectionSort(array, SIZE); break; case 3: printf("The result of Insertion sorting is following:\n"); section4::insertionSort(array, SIZE); break; case 4: printf("The result of Shell sorting is following:\n"); section4::shellSort(array, SIZE); break; case 5: printf("The result of Quick sorting is following:\n"); section4::quickSort(array, 0, SIZE - 1); section4::printfByStep(array, SIZE, SIZE); break; case 6: printf("The result of Heap sorting is following:\n"); section4::heapSort(array, SIZE); break; case 7: printf("The result of Merge sorting is following:\n"); section4::mergeSort(array, SIZE); break; } } // for (i = 0; i < SIZE; i++) { // printf("%d ", array[i]); // } // printf("\n"); return 0; }
1、冒泡排序:
/* * BubbleSort.h * * Created on: 2015年11月16日 * Author: hoojjack */ #pragma once #include "CommonFunction.h" namespace section4 { /* * 冒泡排序,很简单,相邻的两个元素进行比较,将较大的元素往后挪 * 每进行一次循环,排好一个元素 */ void bubbleSort(int *a, int len) { int i, j; for (i = 1; i < len; i++) { for (j = 0; j < len - i; j++) { if (a[j] > a[j + 1]) { swap(&a[j],&a[j+1]); } } //The result of the %dth step //section4::printfByStep(a,i,len); } section4::printfByStep(a,i,len); } }
2、选择排序算法:
/* * SelectionSort.h * * Created on: 2015年11月16日 * Author: hoojjack */ #pragma once #include "CommonFunction.h" namespace section4 { /* * @author * 选择排序,每第i次循环为第i个位置找到此序列相应的第i个数。 */ void selectionSort(int *a,int len){ int i,j,k; for(i=0;i<len;i++){ k=i;//记录此刻要数组中待排的位置 for(j=i;j<len;j++){ if(a[k]>a[j]) k=j; } if(k!=i){ section4::swap(&a[k],&a[i]); } //section4::printfByStep(a,i,len); } section4::printfByStep(a,i,len); } }
3、插入排序算法:
/* * InsertionSort.h * * Created on: 2015年11月16日 * Author: hoojjack */ #pragma once #include "CommonFunction.h" namespace section4{ /* * 此处的插入排序没有安排哨兵,即没有将a[0]空出来 */ void insertionSort(int *a,int len){ int i,temp,j; for(i=1;i<len;i++){ temp=a[i]; j=i-1; while(j>=0&&temp<a[j]){ a[j+1]=a[j]; j--; } a[j+1]=temp; // section4::printfByStep(a,i,len); } section4::printfByStep(a,i,len); } }
4、希尔排序算法:
/* * ShellSort.h * * Created on: 2015年11月16日 * Author: hoojjack */ #pragma once #include "CommonFunction.h" namespace section4 { /* * 希尔排序的思路是:每次以i/2的大小进行插入排序,第一次是以len/2的长度进行比较 * i为相隔的步长,每次以i的步长往前进行比较,直到步长为1。 * */ void shellSort(int *a, int len) { int i, j, temp,k, x = 0; for (i = len / 2; i >= 1; i = i / 2) { for (j = i; j < len; j++) { temp = a[j]; k = j - i; while (temp < a[k] && k >= 0) { a[k + i] = a[k]; k = k - i; } a[k + i] = temp; } x++; //section4::printfByStep(a, x, len); } section4::printfByStep(a, x, len); } }
5、快速排序算法:
/* * QuickSort.h * * Created on: 2015年11月16日 * Author: hoojjack */ #pragma once #include "CommonFunction.h" namespace section4 { /*@author * 快速排序:这是自己按照快速排序的思路写的,刚开始出现两个地方的错误 * 1、递归循环的时候没有判断(left < low - 1)和(high + 1 < right)导致递归的时候 * 出现left值比right值大,以致递归不能结束 * * 2、temp <= a[high] 没有判断=号,导致如果数组里出现相同的数字时,low和high的位置没有变化 * 导致循环不断地在交换a[low]和a[high]的值,出现死循环。 * */ void quickSort(int *a, int left, int right) { int low, high, temp; low = left; high = right; temp = a[low]; while (low < high) { while (temp <= a[high] && low < high) { high--; } a[low] = a[high]; while (temp >= a[low] && low < high) { low++; } a[high] = a[low]; } a[low] = temp; // printf("low=%d,high=%d\n", low, high); if (left < low - 1) quickSort(a, left, low - 1); if (high + 1 < right) quickSort(a, high + 1, right); } }
6堆排序算法:
/* * HeapSort.h * * Created on: 2015年11月17日 * Author: hoojjack */ #pragma once #include "CommonFunction.h" namespace section4 { /* * @author * 堆排序应该注意的几点: * 1、首先从最后一个父节点开始往上堆排序,在计算的时候考虑数组下标,计算 * 最后一个父节点的计算公式是len/2-1(因为数组从0开始编号),然而在算它的孩子几点时 * 左孩子节点不再是2*parent,而是2*parent+1; * 2、对数组进行从小到大排序,需要建立大根堆,因为数字大的排在数组后面 */ void heapSort(int *a, int len) { int child, parent, t, i, j, z; for (i = 0; i < len; i++) { z = len - 1 - i; for (j = ((z + 1) / 2) - 1; j >= 0; j--) { parent = j; while ((2 * parent + 1) <= z) { child = 2 * parent + 1; if ((child + 1) <= z) { if (a[child] > a[child + 1]) { t = child; } else { t = child + 1; } } else { t = child; } if (a[parent] < a[t]) { section4::swap(&a[parent], &a[t]); } else { break; } } } section4::swap(&a[0],&a[z]); //section4::printfByStep(a,i,len); } section4::printfByStep(a,i,len); } }
7、归并排序算法:
/* * MergeSort.h * * Created on: 2015年11月17日 * Author: hoojjack */ #pragma once #include<stdlib.h> #include "CommonFunction.h" namespace section4 { /* * @author * 分步归并函数 * */ void mergeOne(int *a, int *b, int n, int len) { int i, j, s, t, e, k; s = 0; while (s < len) { i = s; t = n + s; j = s + n; e = s + 2 * n - 1; k = s; /*其中,i代表第一个归并子序列的首位,t代表此序列的末位 * j代表第二个归并子序列的首位,e代表此序列的末位 * k代表另一个数组的下标 * e的大小没有进行判断,容易导致最后一次归并时, * 导致下标越界,故一定要判断e是否>=len */ if(e>=len){ e=len-1; } while (i < t && j <= e) { if (a[i] < a[j]) { b[k++] = a[i++]; } else { b[k++] = a[j++]; } } while (i < t) { b[k++] = a[i++]; } while (j <= e) { b[k++] = a[j++]; } //s在此刻第二个归并子序列e的基础前进1 s = e + 1; } // if (s < len) { // for (; s < len; s++) // b[s] = a[s]; // } } /* * 归并函数,b为开辟一个新数组的首地址,f为标志符, * 当f=1时,将数组a中的数复制到数组b中,否则,进行相反操作 * s为每次归并的长度,1,2,2^2,2^3,...... * 直到数组子序列归并为一个,即s<len */ void mergeSort(int *a, int len) { int *b; int f = 1, s = 1, count = 0, h; if (!(b = (int *) malloc(sizeof(int) * len))) { printf("内存分配失败\n"); exit(0); } while (s < len) { if (f == 1) { mergeOne(a, b, s, len); // section4::printfByStep(b, count++, len); } else { mergeOne(b, a, s, len); // section4::printfByStep(a, count++, len); } f = 1 - f; s = s * 2; } if (!f) { for (h = 0; h < len; h++) a[h] = b[h]; } section4::printfByStep(a, count, len); free(b); } }
最后的结果是:
The array of original sorting 31 35 29 12 40 35 24 38 29 38 Please choose your options: 1:BubbleSort 2:Selection 3:InsertSort 4:ShellSort 5:QuickSort 6:HeapSort 7:MergeSort The result of Bubble sorting is following: The result of the 10th step 12 24 29 29 31 35 35 38 38 40 The result of Selection sorting is following: The result of the 10th step 12 24 29 29 31 35 35 38 38 40 The result of Insertion sorting is following: The result of the 10th step 12 24 29 29 31 35 35 38 38 40 The result of Shell sorting is following: The result of the 3th step 12 24 29 29 31 35 35 38 38 40 The result of Quick sorting is following: The result of the 10th step 12 24 29 29 31 35 35 38 38 40 The result of Heap sorting is following: The result of the 10th step 12 24 29 29 31 35 35 38 38 40 The result of Merge sorting is following: The result of the 0th step 12 24 29 29 31 35 35 38 38 40
相关文章推荐
- 【bzoj4236】【JOIJOI】【map】
- MyOS (二) 将磁盘中的程序装载到内存中
- jquery监听按键
- 使用Hierarchy Viewer工具移除不必要的视图
- 《剑指offer》——平衡二叉树
- Connect2015 简要整理
- Codeforces Round #331 (Div. 2) C. Wilbur and Points
- oc框架排名列表
- 海盗问题和汉诺塔问题的分析
- Windows系统中如何配置Apache的SSL加密访问
- android Recyclerview仿京东,滚动屏幕标题栏渐变
- This version of the rendering library is more recent than your version of ADT plug-in. Please update
- 随笔
- 储存出题改进
- gcc编译 汇编 选项
- 反编译apk文件
- chrome设置--disable-web-security解决跨域
- c 可变参数(variable argument)的原理及使用
- static才是对代码的提升
- 微信支付和分享到朋友圈-struts版本