排序是数据结构中一种非常重要的算法,不同的排序时间复杂度也不一样
#include<stdlib.h>
#include<stdio.h>
void swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void adjustdown(int* a, int n, int parent) {
int child = parent * 2 + 1;
while (child < n) {
if (child + 1 < n && a[child] < a[child + 1]) {
child = child + 1;
}
if (a[parent] < a[child]) {
swap(&a[parent], &a[child]);
parent = child;
child = parent * 2 + 1;
}
else {
break;
}
}
}
void heapsort(int* a, int n) {
for (int i = (n - 2) / 2; i >= 0; i--) {
adjustdown(a, n, i);
}
int end = n - 1;
while (end > 0) {
swap(&a[0], &a[end]);
adjustdown(a, end, 0);
end--;
}
}
void printsort(int* a, int n) {
for (int i = 0; i < n; i++) {
printf("%3d", a[i]);
}
}
void heaptest() {
int a[] = { 32,13,45,65,84,68,27 };
int n = sizeof(a) / sizeof(a[0]);
printf("原数组:");
printsort(a, n);
printf("\n");
heapsort(a, n);
printf("heapsort:");
printsort(a, n);
printf("\n");
}
void selectsort(int* a, int n) {
int begin = 0, end = n - 1;
while (begin < end) {
int maxi = begin, mini = begin;
for (int i = begin; i <= end; i++) {
if (a[i] > a[maxi]) {
maxi = i;
}
if (a[i] < a[mini])
{
mini = i;
}
}
swap(&a[begin],&a[mini]);
if (begin == maxi)
{
maxi = mini;
}
swap(&a[end], &a[maxi]);
++begin;
--end;
}
}
void selecttest() {
int a[] = { 32,13,45,65,84,68,27 };
int n = sizeof(a) / sizeof(a[0]);
printf("原数组:");
printsort(a, n);
printf("\n");
selectsort(a, n);
printf("selectsort:");
printsort(a, n);
printf("\n");
}
void insertsort(int* a, int n) {
for (int i = 0; i < n-1; i++) {
int end = i;
int tmp = a[i + 1];
while (end >= 0) {
if (a[end] > tmp) {
a[end + 1] = a[end];
end--;
}
else {
break;
}
}
a[end + 1] = tmp;
}
}
void inserttest() {
int a[] = { 32,13,45,65,84,68,27 };
int n = sizeof(a) / sizeof(a[0]);
printf("原数组:");
printsort(a, n);
printf("\n");
insertsort(a, n);
printf("insertsort:");
printsort(a, n);
printf("\n");
}
void shellsort(int* a, int n) {
int gap =n;
while (gap > 1) {
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; i++) {
int end = i;
int tmp = a[end + gap];
while (end >= 0) {
if (a[end] > tmp) {
a[end + gap] = a[end];
end -= gap;
}
else {
break;
}
}
a[end + gap] = tmp;
}
}
}
void shelltest() {
int a[] = { 32,13,45,65,84,68,27 };
int n = sizeof(a) / sizeof(a[0]);
printf("原数组:");
printsort(a, n);
printf("\n");
insertsort(a, n);
printf("shellsort:");
printsort(a, n);
printf("\n");
}
int main() {
heaptest();
selecttest();
inserttest();
shelltest();
}
堆排序:先构造一个大堆,大堆就是最大的在上面,然后将最大的和最后一个数交换,每次向下调整,end--代表最后的数值不动了
void swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void adjustdown(int* a, int n, int parent) {
int child = parent * 2 + 1;//算出孩子节点
while (child < n) {//当孩子大于n越界的时候结束循环
if (child + 1 < n && a[child] < a[child + 1]) {//如果孩子+1不越界代表有右孩子,然后再看左孩子大还是右孩子大
child = child + 1;//如果右孩子大就+1
}
if (a[parent] < a[child]) {//查看父节点是否小于左孩子
swap(&a[parent], &a[child]);//交换数值
parent = child;
child = parent * 2 + 1;
}
else {
break;
}
}
}
void heapsort(int* a, int n) {
for (int i = (n - 2) / 2; i >= 0; i--) {//从最后一个有子节点的节点开始走,每次向下调整,构建一个大堆
adjustdown(a, n, i);
}
int end = n - 1;//最后一个数值节点的下标
while (end > 0) {
swap(&a[0], &a[end]);//每次交换头尾节点,方便pop
adjustdown(a, end, 0);
end--;//每次pop尾下标减1
}
}
选择排序:选择出最大和最小的值依次放入起点和终点
void selectsort(int* a, int n) {
int begin = 0, end = n - 1;//确定起始位置和终止位置
while (begin < end) {
int maxi = begin, mini = begin;//最大值和最小值一开始都给begin
for (int i = begin; i <= end; i++) {
if (a[i] > a[maxi]) {//如果i的值大于max则赋值
maxi = i;
}
if (a[i] < a[mini])//如果i的值小于min则赋值
{
mini = i;
}
}
swap(&a[begin],&a[mini]);//把最小的给begin
if (begin == maxi)// 如果maxi和begin重叠,修正一下即可
{
maxi = mini;
}
swap(&a[end], &a[maxi]);//把最大的给max
++begin;
--end;
}
}
插入排序:每次和前面一个数比较
void insertsort(int* a, int n) {
for (int i = 0; i < n-1; i++) {
int end = i;//从i开始
int tmp = a[i + 1];//tmp等于i的下一个位置的数值 方便比较
while (end >= 0) {
if (a[end] > tmp) {//如果end下标的数值大于tmp的移动到下一个位置
a[end + 1] = a[end];
end--;//end--意味着每次和前面的数值去比较,不断叠加
}
else {
break;
}
}
a[end + 1] = tmp;//插入到合适位置
}
}
希尔排序:每次和gap差比较
void shellsort(int* a, int n) {
int gap =n;//令gap等于数组的长度
while (gap > 1) {//当gap大于1的时候继续走,gap取值有1,2,3
gap = gap / 3 + 1;//加1可以让gap不等于0
for (int i = 0; i < n - gap; i++) {//n-gap防止a[end+gap]越界
int end = i;
int tmp = a[end + gap];
while (end >= 0) {
if (a[end] > tmp) {
a[end + gap] = a[end];
end -= gap;//每次-gap比较
}
else {
break;
}
}
a[end + gap] = tmp;
}
}
}