You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
6.8 KiB
266 lines
6.8 KiB
#include <stdio.h>
|
|
|
|
// 1.插入排序,时间复杂度O(n2),空间复杂度O(1)
|
|
void InsertSort(int a[], int n)
|
|
{
|
|
for (int i = 1; i < n; i++)
|
|
{
|
|
// 若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
|
|
if (a[i] < a[i - 1])
|
|
{
|
|
int j = i - 1;
|
|
// 复制为哨兵,即存储待排序元素
|
|
int x = a[i];
|
|
// 先后移一个元素
|
|
a[i] = a[i - 1];
|
|
// 查找在有序表的插入位置
|
|
while (x < a[j])
|
|
{
|
|
a[j + 1] = a[j];
|
|
// 元素后移
|
|
j--;
|
|
}
|
|
// 插入到正确位置
|
|
a[j + 1] = x;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2.希尔排序,时间复杂度O(N^1.5),空间复杂度O(1)
|
|
void ShellInsertSort(int a[], int n, int dk)
|
|
{
|
|
for (int i = dk; i < n; ++i)
|
|
{
|
|
if (a[i] < a[i - dk])
|
|
{ // 若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
|
|
int j = i - dk;
|
|
int x = a[i]; // 复制为哨兵,即存储待排序元素
|
|
a[i] = a[i - dk]; // 首先后移一个元素
|
|
while (j >= 0 && x < a[j])
|
|
{ // 查找在有序表的插入位置
|
|
a[j + dk] = a[j];
|
|
j -= dk; // 元素后移
|
|
}
|
|
a[j + dk] = x; // 插入到正确位置
|
|
}
|
|
}
|
|
}
|
|
void ShellSort(int a[], int n)
|
|
{
|
|
|
|
int dk = n / 2;
|
|
while (dk >= 1)
|
|
{
|
|
ShellInsertSort(a, n, dk);
|
|
dk = dk / 2;
|
|
}
|
|
}
|
|
|
|
// 选择排序,时间复杂度:O(N^2), 空间复杂度:O(1)
|
|
int SelectMinKey(int a[], int n, int i)
|
|
{
|
|
int k = i;
|
|
for (int j = i + 1; j < n; ++j)
|
|
{
|
|
if (a[k] > a[j])
|
|
k = j;
|
|
}
|
|
return k;
|
|
}
|
|
void SelectSort(int a[], int n)
|
|
{
|
|
int key, tmp;
|
|
for (int i = 0; i < n - 1; ++i)
|
|
{
|
|
key = SelectMinKey(a, n, i); // 选择最小的元素
|
|
if (key != i)
|
|
{
|
|
tmp = a[i];
|
|
a[i] = a[key];
|
|
a[key] = tmp; // 最小元素与第i位置元素互换
|
|
}
|
|
}
|
|
}
|
|
|
|
// 堆排序,时间复杂度:O(N*logN),空间复杂度:O(1)
|
|
void HeapAdjust(int H[], int s, int length)
|
|
{
|
|
int tmp = H[s];
|
|
int child = 2 * s + 1; // 左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)
|
|
while (child < length)
|
|
{
|
|
if (child + 1 < length && H[child] < H[child + 1])
|
|
{ // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)
|
|
++child;
|
|
}
|
|
if (H[s] < H[child])
|
|
{ // 如果较大的子结点大于父结点
|
|
H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点
|
|
s = child; // 重新设置s ,即待调整的下一个结点的位置
|
|
child = 2 * s + 1;
|
|
}
|
|
else
|
|
{ // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出
|
|
break;
|
|
}
|
|
H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 初始堆进行调整
|
|
* 将H[0..length-1]建成堆
|
|
* 调整完之后第一个元素是序列的最小的元素
|
|
*/
|
|
void BuildingHeap(int H[], int length)
|
|
{
|
|
// 最后一个有孩子的节点的位置 i= (length -1) / 2
|
|
for (int i = (length - 1) / 2; i >= 0; --i)
|
|
HeapAdjust(H, i, length);
|
|
}
|
|
/**
|
|
* 堆排序算法
|
|
*/
|
|
void HeapSort(int H[], int length)
|
|
{
|
|
// 初始堆
|
|
BuildingHeap(H, length);
|
|
// 从最后一个元素开始对序列进行调整
|
|
for (int i = length - 1; i > 0; --i)
|
|
{
|
|
// 交换堆顶元素H[0]和堆中最后一个元素
|
|
int temp = H[i];
|
|
H[i] = H[0];
|
|
H[0] = temp;
|
|
// 每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整
|
|
HeapAdjust(H, 0, i);
|
|
}
|
|
}
|
|
|
|
// 冒泡排序,时间复杂度:O(N^2),空间复杂度:O(1)
|
|
void BubbleSort(int r[], int n)
|
|
{
|
|
int low = 0;
|
|
int high = n - 1; // 设置变量的初始值
|
|
int tmp, j;
|
|
while (low < high)
|
|
{
|
|
for (j = low; j < high; ++j) // 正向冒泡,找到最大者
|
|
if (r[j] > r[j + 1])
|
|
{
|
|
tmp = r[j];
|
|
r[j] = r[j + 1];
|
|
r[j + 1] = tmp;
|
|
}
|
|
--high; // 修改high值, 前移一位
|
|
for (j = high; j > low; --j) // 反向冒泡,找到最小者
|
|
if (r[j] < r[j - 1])
|
|
{
|
|
tmp = r[j];
|
|
r[j] = r[j - 1];
|
|
r[j - 1] = tmp;
|
|
}
|
|
++low; // 修改low值,后移一位
|
|
}
|
|
}
|
|
|
|
// 快速排序递归实现,时间复杂度:O(N*logN), 空间复杂度:O(logN)
|
|
int QuickSort(int *a, int low, int high)
|
|
{
|
|
int i = low; // 第一位
|
|
int j = high; // 最后一位
|
|
int key = a[i]; // 将第一个数作为基准值-- 先找到一个基准值
|
|
|
|
while (i < j)
|
|
{
|
|
while (i < j && a[j] >= key)
|
|
{
|
|
j--;
|
|
}
|
|
a[i] = a[j];
|
|
|
|
while (i < j && a[i] <= key)
|
|
{
|
|
i++;
|
|
}
|
|
a[j] = a[i];
|
|
}
|
|
a[i] = key;
|
|
if (i - 1 > low)
|
|
{
|
|
QuickSort(a, low, i - 1);
|
|
}
|
|
|
|
if (i + 1 < high)
|
|
{
|
|
QuickSort(a, i + 1, high);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// 归并排序迭代实现,时间复杂度:O(N*logN), 空间复杂度:O(N)
|
|
void merge(int arr[], int start, int mid, int end, int len)
|
|
{
|
|
int result[len];
|
|
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, int len)
|
|
{
|
|
if (start >= end)
|
|
return;
|
|
int mid = (start + end) / 2;
|
|
MergeSort(arr, start, mid, len);
|
|
MergeSort(arr, mid + 1, end, len);
|
|
merge(arr, start, mid, end, len);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int i;
|
|
int array[] = {9, 5, 6, 1, 4, 7, 3, 8, 2};
|
|
int array2[9];
|
|
// InsertSort(array, sizeof(array)/sizeof(array[0]));
|
|
// ShellSort(array, sizeof(array)/sizeof(array[0]));
|
|
// SelectSort(array, sizeof(array)/sizeof(array[0]));
|
|
// HeapSort(array, sizeof(array)/sizeof(array[0]));
|
|
// BubbleSort(array, sizeof(array)/sizeof(array[0]));
|
|
// QuickSort(array, 0, 9-1);
|
|
int len = sizeof(array) / sizeof(array[0]);
|
|
MergeSort(array, 0, 9 - 1, len);
|
|
|
|
printf("sort result is:");
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
printf("%d", array[i]);
|
|
}
|
|
return 0;
|
|
}
|