排序算法的原理在此就不再叙述,后面代码里面注释也有原理的体现
数据结构链接汇总:
目录
1.插入排序
#include<stdio.h>
#include<stdlib.h>
//时间复杂度分析:该排序算法的时间复杂度为O(n的平方)
//该算法没有改变之前的相对顺序,所以是一个稳定的排序算法
void insertsort(int arr[], int n)
{
int i, j;
for (i = 1; i < n; i++)
{
int tmp = arr[i];
if (tmp > arr[i - 1])
{
for (j = i - 1; j <= 0 && tmp > arr[j]; j--)
{
arr[j + 1] = arr[j];
}
arr[j + 1] = tmp;
}
}
}
//插入排序算法的一种改进
//由于插入排序算法在排序过程中不断地寻找合适的位置和移动数据
//所以为减少排序的时间,我们采用折半查找找出数据应该插入
int binarysort(int arr[], int n)//折半插入排序
{
int i, j;
int low, high, mid;
int tmp;
for (i = 1; i < n; i++)
{
tmp = arr[i];
low = 0;
high = i - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (tmp > arr[mid])
{
high = mid - 1;
}
else {
low = mid + 1;
}
}
for (j = i - 1; j >= high + 1; j--)
{
arr[j + 1] = arr[j];
}
arr[high + 1] = tmp;//将待排序的序列插入有序序列中
}
}
//折半查找虽然节省了排序过程中比较的次数,但是移动的次数与直接插入排序,算法的时间复杂度为仍然为O(n的平方)
//直接插入算法的再次改进,希尔排序算法,既减少了数据移动的次数,又减少了比较的次数
//希尔排序算法是一个不稳定的排序算法
//希尔排序算法的时间复杂度为O(n的1.3次方),时间复杂度与设置的步长增量有关
//希尔排序算法是一个不稳定排序算法
//希尔排序算法的代码实现
void shellsort(int arr[], int n)
{
int i, j, d;
int tmp;
d = n / 2;
while (d > 0)
{
for (i = d; i < n; i++)
{
tmp = arr[i];
j = i - d;
while (j >= 0 && tmp > arr[j])
{
arr[j + d] = arr[j];
j = j - d;
}
arr[j + d] = tmp;
}
d = d / 2;
}
}
2.堆排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void heapify(int arr[], int i, int n)//建堆算法
{
int nchild;
int tmp;
for (; 2 * i + 1< n; i = nchild)
{
nchild = 2 * i + 1;
if (nchild<n - 1 && arr[nchild + 1]>arr[nchild])
nchild++;
if (arr[i] < arr[nchild])
{
tmp = arr[i];
arr[i] = arr[nchild];
arr[nchild] = tmp;
}
}
}
void heapsort(int arr[], int n)
{
int i;
for (i = (n - 1) / 2; i >= 0; i--)
{
heapify(arr, i, n);
}
for (i = n - 1; i > 0; i--)
{
//把第一个元素与当前最后一元素交换
arr[i] = arr[0] ^ arr[i];
arr[0] = arr[0] ^ arr[i];
arr[i] = arr[0] ^ arr[i];
//不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
heapify(arr, 0, i);
}
}
3.归并排序
#include<stdio.h>
#define ArrLen 20
void printList(int arr[], int len) {
int i;
for (i = 0; i < len; i++) {
printf("%d\t", arr[i]);
}
}
void merge(int arr[], int start, int mid, int end) {
int result[ArrLen];
int k = 0;
int i = start;
int j = mid + 1;
while (i <= mid && j <= end) {
if (arr[i] < arr[j]){
result[k++] = arr[i++];
}
else{
result[k++] = arr[j++];
}
}
if (i == mid + 1) {
while(j <= end)
result[k++] = arr[j++];
}
if (j == end + 1) {
while (i <= mid)
result[k++] = arr[i++];
}
for (j = 0, i = start ; j < k; i++, j++) {
arr[i] = result[j];
}
}
void mergeSort(int arr[], int start, int end) {
if (start >= end)
return;
int mid = ( start + end ) / 2;
mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
merge(arr, start, mid, end);
}
int main()
{
int arr[] = {4, 7, 6, 5, 2, 1, 8, 2, 9, 1};
mergeSort(arr, 0, 9);
printList(arr, 10);
system("pause");
return 0;
}
4.交换排序
#include<stdio.h>
#include<stdlib.h>
void swap(int* a, int* b)//交换函数
{
int temp = *a;
*a = *b;
*b = temp;
}
void sort(int arr[], int n)//基本的交换排序
{
int i, j;
int k;
for (i = 0; i < n-1; i++)
{
for (j = i+1; j < n; j++)
{
if (arr[i] < arr[j])
{
swap(&arr[i], &arr[j]);
}
}
}
}
5.快速排序
//简单介绍:快速排序的基本思想就是:通过一趟排序将序列分为两部分,一部分比另外一部分的所有值都要小;然按照此方法,对较小的两个部分继续进行排序,
//直到整个序列变得有序未知,通常把第一个值作为关键值
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//快速排序算法 平均的时间复杂度为O(nlogn),最坏的情况下与冒泡排序的复杂度一样
//对于快速排序的空间复杂度,在排序过程只需要常数级的辅助空间,因此排序的空间的复杂度为O(1),但是需要多次调用栈,这个空间的大小为nlogn,所以总的空间复杂度为O(nlogn)
void quicksort(int arr[],int left,int right)
{
if (left >= right)
{
return;
}
int key = arr[left];
int i = left, j = right;
while (i <j)
{
while ((i < j) && (key <= arr[j]))
{
j--;
}
arr[i] = arr[j];
while ((i < j) && (key >= arr[i]))
{
i++;
}
arr[j] = arr[i];
arr[i] = key;
quicksort(arr, left, i - 1);
quicksort(arr, i + 1, right);
}
}
int main()
{
int a[11] = { 1,123,12,12345,234,234567,432,5677,345775,34235244,23444 };
quicksort(a, 0, 10);
for (int i = 0; i < 11; i++)
{
printf("%d ", a[i]);
}
return 0;
}
6.冒泡排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//冒泡排序算法的复杂度为O(n的平方), 冒牌排序是稳定的排序
void 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])
{
swap(&arr[j], &arr[j + 1]);
}
}
}
}
//冒泡排序算法的一种改进
//很显然冒泡排序中间过程中,较小的数据逐渐靠近合适的位置,我们可以设置标志位减少一些不必要的排序过程
void Bubblesort_B(int arr[], int n)
{
int flag = 1;
for (int i = 0; i < n - 1&&flag==1; i++)
{
flag = 0;
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] < arr[j + 1])
{
flag = 1;//没有发生交换就停止
swap(&arr[j], &arr[j + 1]);
}
}
}
}
7.选择排序
//选择排序
//1.简单的选择排序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//简单的选择排序包含可一个双层循环,时间复杂度为为O(n的平方)
//简单选择排序不是一个稳定的算法
void selectsort(int arr[], int n)
{
int i, j, max;
for (i = 0; i < n; i++)
{
max = i;
for (j = i; i < n; j++)
{
if (arr[max] < arr[j])
{
max = j;
}
}
if (i != max)
{
swap(&arr[i], &arr[max]);
}
}
}
//树形选择排序
//时间复杂度为nlogn