部分排序算法的源代码实现

插入排序

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);
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值