插入排序
void InsertSort(int* array, int size)
{
int tmp = array[1];
for (int i = 1; i < size; ++i)
{
tmp = array[i];
int j = i - 1;
while (j >= 0)
{
if (array[i] < array[j])
{
array[i] = array[j];
array[j] = tmp;
--i;
--j;
}
else
--j;
}
}
}
void O_InsertSort(int* array, int size)
{
for (int i = 1; i < size; ++i)
{
int internal = i - 1;
int external = array[i];
while (internal >= 0 && array[internal] > external)
{
array[internal + 1] = array[internal];
--internal;
}
array[internal + 1] = external;
}
}
希尔排序
void ShellSort(int* array, int size)
{
for (int gap = size / 2; gap > 1; gap /= 2)
{
int n = gap;
int j = 0;
while (n >= 1)
{
for (int i = j; i + gap < size; i += gap)
{
if (array[i] > array[i + gap])
{
int tmp = array[i];
array[i] = array[i + gap];
array[i + gap] = tmp;
}
}
--n;
++j;
}
}
InsertSort(array, size);
}
void O_ShellSort(int* array, int size)
{
for (int gap = size / 2; gap > 0; gap /= 2)
{
for (int i = gap; i < size;++i)
{
int tmp = array[i];
int j = i;
for (; j >= gap && tmp < array[j -gap]; j -= gap)
{
array[j] = array[j - gap];
}
array[j] = tmp;
}
}
}
简单选择排序
void SelectSort(int* array, int size)
{
int max_index = 0;
int rightmost = size - 1;
while (rightmost)
{
max_index = 0;
for (int i = 0; i <= rightmost; ++i)
{
if (array[max_index] < array[i])max_index = i;
}
if(max_index != rightmost)swap(&array[max_index], &array[rightmost]);
--rightmost;
}
}
void O_SelectSort(int* array, int size)
{
int max = 0, min = size - 1;
int rightmost = size - 1, leftmost = 0;
while (rightmost > leftmost)
{
for (int i = leftmost; i <= rightmost; ++i)
{
if(array[max] < array[i])max = i;
if (array[min] > array[i])min = i;
}
if(max != rightmost)swap(&array[rightmost], &array[max]);
if (min == rightmost)min = max;// Adjust min if it was swapped
if(min != leftmost)swap(&array[leftmost], &array[min]);
++leftmost;
--rightmost;
max = leftmost;
min = rightmost;
}
}
堆排序
//void HeapSort(int* array, int size)
//{
// //Build the heap
// for (int i = size - 1; i >= 0; --i)
// {
// Adjustdown(array, (i -1)/2, size);
// }
// //Sort the last layer of heap
// for (int i = size - 1; i > (i - 1) / 2; --i)
// {
// O_SelectSort(&array[((i - 1) / 2) + 1], i - ((i - 1) / 2));
// }
//}
// void Adjustdown(int* array, int root,int size)
//{
// int parent = root;
// int child = root * 2 + 1;
// while (size > child)
// {
// if (child + 1 < size && array[child] > array[child + 1])swap(&array[child + 1],&array[child];
// if (array[parent] > array[child])
// {
// swap(&array[parent], &array[child]);
// parent = child;
// child = child * 2 + 1;
// }
// else
// break;
// }
//}
//When building a heap, the array is partially ordered
//because each parent node is larger than its child nodes,
//maintaining the max - heap property.However,
//when I attempted to sort the nodes at the same level of the heap,
//I mistakenly focused only on sorting sibling nodes(nodes with the same parent).
//The issue arises because even though the nodes at the last layer may be ordered,
//the middle parent nodes remain unordered.Sorting only the last layer does not guarantee the heap is fully sorted,
//as this overlooks the fact that the relationships between parent and
//child nodes in different parts of the heap may still violate the heap property.
//Therefore, my approach was flawed because it didn't account for maintaining order across the entire heap.
//The correct method requires not just sorting sibling nodes,
//but also ensuring that the heap property is maintained globally by
//adjusting the heap from top to bottom after each extraction of the maximum element.
//So to sort in asending order, you must build a max heap.
void HeapSort(int* array, int size)
{
for (int i = size - 1; i >= 0; --i)
{
Adjustdown(array, (i - 1) / 2, size);
}
for (int i = size - 1; i > 0; --i)
{
swap(&array[0], &array[i]);
Adjustdown(array, 0, i);
}
}
void Adjustdown(int* array, int root,int size)
{
int parent = root;
int child = root * 2 + 1;
while(size > child)
{
if (child + 1 < size && array[child] < array[child + 1])++child;
if (array[parent] < array[child])
{
swap(&array[parent], &array[child]);
parent = child;
child = child * 2 + 1;
}
else
break;
}
}
冒泡排序
void BubbleSort(int* array, int size)
{
for (int i = 0; i < size - 1 ; ++i)
{
for (int j = 0 ; j < size -i - 1; ++j)
{
if (array[j] > array[j + 1])swap(&array[j], &array[j + 1]);
}
}
}
快速排序
void QuickSort(int* array, int begin,int end)
{
if (begin >= end)return;
int indexofkey = O3_PartSort(array, begin, end);
QuickSort(array, begin, indexofkey - 1);
QuickSort(array, indexofkey + 1,end);
}
int PartSort(int* array, int leftmost, int rightmost)
{
int key = leftmost;
while (leftmost < rightmost)
{
while (leftmost < rightmost &&
array[rightmost] >= array[key])
--rightmost;//Find the number less than kry
while (leftmost < rightmost &&
array[leftmost] <= array[key])
++leftmost;//Find the larger
if (leftmost < rightmost)
swap(&array[leftmost], &array[rightmost]);
}
swap(&array[key], &array[leftmost]);
return leftmost;
}
int O1_PartSort(int* array, int leftmost, int rightmost)
{
int median = leftmost + (rightmost - leftmost) / 2;
if (array[leftmost] > array[rightmost] &&
array[leftmost] < array[median])
median = leftmost;
else if (array[rightmost] > array[leftmost]
&& array[rightmost] < array[median])
median = rightmost;
if (leftmost != median)
{
swap(&array[leftmost], &array[median]);//Ensure the leftmost is key
median = leftmost;
}
while (leftmost < rightmost)
{
while (leftmost < rightmost &&
array[rightmost] >= array[median])
--rightmost;
while (leftmost < rightmost &&
array[leftmost] <= array[median])
++leftmost;
if (rightmost > leftmost)
swap(&array[leftmost], &array[rightmost]);
}
if (array[median] > array[leftmost])
{
swap(&array[median], &array[leftmost]);
median = leftmost;
}
return median;
}
int O2_PartSort(int* array, int leftmost, int rightmost)
{
int median = leftmost + (rightmost - leftmost) / 2;
if (array[leftmost] > array[rightmost] &&
array[leftmost] < array[median])
median = leftmost;
else if (array[rightmost] > array[leftmost] &&
array[rightmost] < array[median])
median = rightmost;
int key = array[median];
if (leftmost != median)
swap(&array[leftmost], &array[median]);//Ensure the leftmost is key
while (leftmost < rightmost)
{
while (leftmost < rightmost && array[rightmost] >= key)--rightmost;
if (leftmost < rightmost)array[leftmost] = array[rightmost];
while (leftmost < rightmost && array[leftmost] <= key)++leftmost;
if (leftmost < rightmost)array[rightmost] = array[leftmost];
}
array[leftmost] = key;
return leftmost;
}
int O3_PartSort(int* array, int leftmost, int rightmost)
{
int median = leftmost + (rightmost - leftmost) / 2;
if (array[leftmost] > array[rightmost] &&
array[leftmost] < array[median])
median = leftmost;
else if (array[rightmost] > array[leftmost] &&
array[rightmost] < array[median])
median = rightmost;
if (leftmost != median)
swap(&array[leftmost], &array[median]);
int prev = leftmost;
int cur = leftmost + 1;
while (cur <= rightmost)
{
if (array[cur] < array[median] && ++prev != cur)
swap(&array[cur], &array[prev]);
++cur;
}
swap(&array[prev], &array[median]);
return prev;
}
归并排序
void MergeSort(int* array, int left,int right)
{
if (left >= right)return;
int median = left + (right - left) / 2;
MergeSort(array, left, median);
MergeSort(array, median + 1, right);
In_Merge(array, left, median, right);
}
void In_Merge(int* array, int left, int median, int right)
{
int sl = median - left + 1;//size of left subarray
int sr = 1;
if (right != median) sr = right - median;
int* left_array = (int*)malloc(sl * sizeof(int));
if (left_array == nullptr)
{
exit(1);
}
int* right_array = (int*)malloc(sr * sizeof(int));
if (right_array == nullptr)
{
exit(1);
}
for (int i = 0; i < sl; ++i)
{
left_array[i] = array[left + i];
}
for (int i = 0; i < sr; ++i)
{
right_array[i] = array[median + 1 + i];
}
int i_l = 0, i_r = 0 ,i_a = left;
while (i_l < sl && i_r < sr)
{
if (left_array[i_l] >= right_array[i_r])
{
array[i_a] = right_array[i_r];
++i_r;
}
if (left_array[i_l] < right_array[i_r])
{
array[i_a] = left_array[i_l];
++i_l;
}
++i_a;
}
while (i_l < sl)
{
array[i_a] = left_array[i_l];
++i_l;
++i_a;
}
while (i_r < sr)
{
array[i_a] = right_array[i_r];
++i_r;
++i_a;
}
free(left_array);
free(right_array);
}
外部归并
void Ex_MergeSort(const char* file)
{
FILE* out = fopen(file, "r");
if (out == nullptr)exit(1);
int i = 0;
int filecount = 0;
const int size = 6;
int num = 0;
int array[size];
char subfilename[20];
memset(array, 0, sizeof(int)*size);
if (fscanf(out, "%d\n", &num) != EOF) {
do {
if (i < size) {
array[i++] = num;
}
else {
// Sort the current chunk
QuickSort(array, 0, size - 1);
// Write sorted chunk to a subfile
char subfilename[20];
sprintf(subfilename, "subfile%d.txt", ++filecount);
FILE* in = fopen(subfilename, "w");
if (in == NULL) {
printf("Error creating subfile\n");
exit(2);
}
for (int j = 0; j < size; ++j) {
fprintf(in, "%d\n", array[j]);
}
fclose(in);
// Start a new chunk
array[0] = num;
i = 1;
}
} while (fscanf(out, "%d\n", &num) != EOF);
// Handle the last chunk if there are remaining elements
if (i > 0) {
QuickSort(array, 0, i - 1);
// Write remaining sorted elements to a new subfile
char subfilename[20];
sprintf(subfilename, "subfile%d.txt", ++filecount);
FILE* in = fopen(subfilename, "w");
if (in == NULL) {
printf("Error creating subfile\n");
exit(2);
}
for (int j = 0; j < i; ++j) {
fprintf(in, "%d\n", array[j]);
}
fclose(in);
}
}
fclose(out);
char f1[20], f2[20], mergefile[20];
int merge_suffix = 0;
int k = filecount;
while (k > 1)
{
sprintf(f1, "subfile%d.txt", k);
sprintf(f2, "subfile%d.txt", k - 1);
sprintf(mergefile, "merge%d.txt", merge_suffix);
Ex_Merge(f1, f2, mergefile);
remove(f1);
remove(f2);
rename(mergefile, f1);
++merge_suffix;
k -= 2;
}
}
void Ex_Merge(const char* s1, const char* s2,const char* out)
{
FILE* f1 = fopen(s1, "r");
FILE* f2 = fopen(s2, "r");
FILE* fout = fopen(out, "w");
if (f1 == nullptr || f2 == nullptr || out == nullptr)exit(3);
int num1, num2;
int readf1 = fscanf(f1, "%d",&num1);
int readf2 = fscanf(f2, "%d", &num2);
while (readf1 != EOF && readf2 != EOF)
{
if (num1 <= num2)
{
fprintf(fout, "%d\n", num1);
readf1 = fscanf(f1, "%d", &num1);
}
if (num2 < num1)
{
fprintf(fout, "%d\n", num2);
readf2 = fscanf(f2, "%d",&num2);
}
}
while (readf1 != EOF)
{
fprintf(fout, "%d\n", num1);
readf1 = fscanf(f1, "%d", &num1);
}
while (readf2 != EOF)
{
fprintf(fout, "%d\n", num2);
readf2 = fscanf(f2, "%d", &num2);
}
fclose(f1);
fclose(f2);
fclose(fout);
}