数据结构初阶 排序实现 个人随堂笔记

排序的实现

#include<string.h>
#include<assert.h>
#include<stdbool.h>

void Print(int* arr, int n);

void InsertSort(int* arr, int n);

void ShellSort(int* arr, int n);

void BubbleSort(int* arr, int n);

void HeapSort(int* arr, int n);

void SelectSort(int* arr, int n);

void CountSort(int* a, int n);

void QuickSort1(int* arr, int begin, int end);
int  Quick1(int* arr, int begin, int end);

void QuickSort2(int* arr, int begin, int end);
int  Quick2(int* arr, int begin, int end);

void QuickSort3(int* arr, int begin, int end);
int  Quick3(int* arr, int begin, int end);

void MergeSort(int* arr, int n);
void Merge(int* arr, int* temp, int begin, int end);

void QuickSort4(int* arr, int begin, int end);
int  Quick4(int* arr, int begin, int end);

void QuickSortNonR(int* arr, int left, int right);
void MergeSortNonR(int* arr, int n);


//非递归实现快速排序时栈的声明
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
STDataType STTop(ST* ps);

int STSize(ST* ps);
bool STEmpty(ST* ps);

函数的实现

基础函数

void Print(int* arr,int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d	", arr[i]);
	}
	printf("\n");

}

void Swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

插入排序的实现

void InsertSort(int* arr,int n)
{
	for (int i = 0; i < n-1; i++)
	{
		int end = i;
		int temp = arr[end + 1];
		while (end >=0)
		{
			if (arr[end] > temp)
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else
				break;

		}
		arr[end+1] = temp;
	}
}

希尔排序的实现

void ShellSort(int* arr, int n)
{	
	int gap = n / 2;
	while (gap >= 1)
	{
		for (int i = 0; i < n-gap; i++)
		{
			int end = i;
			int temp = arr[gap +end];
			while (end >= 0)
			{
				if (arr[end] > temp)
				{
					arr[end +gap] = arr[end];
					end-=gap;
				}
				else
					break;

			}
			arr[end + gap] = temp;
		}
		gap = gap / 2;
	}
}

冒泡排序的实现

void BubbleSort(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n - i-1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				Swap(arr+j, arr+j + 1);
			}
		}
	}
}

堆排序的实现

void Adjustdown(int* arr,int parent,int n)
{
	while (parent < n-1)
	{
		int child = parent * 2 + 1;//向上调整建大堆
		if (child + 1 < n - 1 && arr[child] < arr[child + 1])
			child++;
		if (child<n-1&&arr[parent] < arr[child])
			Swap(arr + parent, arr + child);
		parent = child;
	}

}
void HeapSort(int* arr, int n)
{
	for(int i=(n-1-1)/2;i>=0;i--)
	{
		Adjustdown(arr, i,n);
	}
	for (int i = n-1; i > 0; i--)
	{
		Swap(arr+0, arr + i);
		Adjustdown(arr, 0, i);
	}
}

搜索排序的实现

void SelectSort(int* arr, int n)
{
	int left = 0, right = n - 1;

	while (left < right)
	{
		int max = arr[left], min = arr[left];
		int maxi =right, mini = left;
		for (int i = left+1; i <= right; i++)
		{
			if (arr[i] > max)
			{
				max = arr[i];
				maxi = i;
			}
			if (arr[i] < min)
			{
				min = arr[i];
				mini = i;
			}
		}
		
		Swap(arr + left, arr + mini);
		if (maxi == left)
		{
			maxi = mini;
		}
		Swap(arr + right, arr + maxi);

		left++;
		right--;
	}
}

计数排序的实现

void CountSort(int* arr, int n)
{
	int min = arr[0], max = arr[0];
	for (int i = 0; i < n - 1; i++)
	{
		if (arr[i] < arr[min])
			min = i;
		if (arr[i] > arr[max])
			max = i;
	}
	int gap = arr[max]-arr[min];
	int* temp = (int*)malloc(sizeof(int) * (gap+1));
	memset(temp, 0, (gap + 1)*sizeof(int));
	for (int i = 0; i < n ; i++)
	{
		temp[arr[i] -arr[min]]++;
	}
	int j = 0;
	for (int i = 0; i < gap+1; i++)
	{
		while (temp[i]--)
		{
			arr[j++] = i + min;
		}
	}
	free(temp);
}

快速排序的三种实现
hoare法

void QuickSort1(int* arr, int begin, int end)
{
	if (begin >=end)
		return;
	int keyi = Quick1(arr, begin, end);
	QuickSort1(arr, begin, keyi - 1);
	QuickSort1(arr, keyi + 1, end);
}

int  Quick1(int* arr, int begin, int end)
{
	int key = begin;
	while (begin < end)
	{
		while (begin<end&&arr[end] >=arr[ key])
		{
			end--;
		}
		while (begin<end&&arr[begin] <= arr[key])
		{
			begin++;
		}
		Swap(&arr[begin], &arr[end]);
	}
	Swap(&arr[key], &arr[begin]);
	return begin;
}

挖坑法

void QuickSort2(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int key = Quick2(arr, begin, end);
	QuickSort2(arr, begin, key - 1);
	QuickSort2(arr, key + 1, end);
}
int  Quick2(int* arr, int begin, int end)
{
	int hole = begin;
	int temp = arr[begin];
	while (begin < end)
	{
		while (begin < end && arr[end] >= temp)
		{
			end--;
		}
		Swap(&arr[hole], &arr[end]);
		hole = end;
		while (begin < end && arr[begin] <= temp)
		{
			begin++;
		}
		Swap(&arr[hole], &arr[begin]);
		hole = begin;
	}
	return hole;
}

前后指针法

void QuickSort3(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int key = Quick3(arr, begin, end);
	QuickSort3(arr, begin, key - 1);
	QuickSort3(arr, key + 1, end);
}
int  Quick3(int* arr, int begin, int end)
{
	int key = arr[begin];
	int cur = begin, prev = begin + 1;
	while (prev <=end)
	{
		if (arr[prev] < key && ++cur < prev)
		{
			Swap(&arr[prev],& arr[cur]);
		}
		prev++;
	}
	Swap(&arr[cur], &arr[begin]);
	return cur;
}

快速排序的优化
三数取中

int TheMid(int* arr,int begin, int end, int mid)
{
	if (arr[begin] > arr[end])
	{
		if (arr[begin] < arr[mid])
			return begin;
		else if (arr[end] > arr[mid])
			return end;
		else
			return mid;
	}
	else
	{
		if (arr[end] <arr[mid])
			return end;
		else if (arr[begin] > arr[mid])
			return begin;
		else
			return mid;
	}
}

小区间的排序选择

int  Quick4(int* arr, int begin, int end)
{
	Swap(&arr[TheMid(arr, begin, end, (begin + end) / 2)], &arr[begin]);
	int hole = begin;
	int temp = arr[begin];
	while (begin < end)
	{
		while (begin < end && arr[end] >= temp)
		{
			end--;
		}
		Swap(&arr[hole], &arr[end]);
		hole = end;
		while (begin < end && arr[begin] <= temp)
		{
			begin++;
		}
		Swap(&arr[hole], &arr[begin]);
		hole = begin;
	}
	return hole;
}
void QuickSort4(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	if (end - begin + 1 > 10)
	{
		int key = Quick4(arr, begin, end);
		QuickSort4(arr, begin, key - 1);
		QuickSort4(arr, key + 1, end);
	}
	else
		InsertSort(arr + begin, end - begin + 1);
}

非递归实现快速排序

用栈的的实现
栈的声明

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
STDataType STTop(ST* ps);

int STSize(ST* ps);
bool STEmpty(ST* ps);

栈的实现

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	// 11:40
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}

STDataType STTop(ST* ps)
{
	assert(ps);

	// 
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}
void QuickSortNonR(int* arr, int left,int right)
{
	ST st;
	STInit(&st);

	STPush(&st, right);
	STPush(&st, left);
	while (!STEmpty(&st))
	{
		int begin = STTop(&st);
		STPop(&st);

		int end = STTop(&st);
		STPop(&st);

		int key = Quick1(arr, begin, end);

		if (key +1< end)
		{
			STPush(&st, end);
			STPush(&st, key+1);
		}
		if (left < key-1)
		{
			STPush(&st, key-1);
			STPush(&st, begin);
		}	
	}
	STDestroy(&st);
}

优化与非递归快速排序的测试

void testQuickSort4()
{
	int arr[] = { 6,1,5,9,4,5,666,9,12,3,99,82,2,78 };
	QuickSort4(arr, 0, sizeof(arr) / sizeof(int) - 1);
	Print(arr, sizeof(arr) / sizeof(int));
}
void testQuickSortNonR()
{
	int arr[] = { 6,1,5,9,4,5,666,9,12,3,99,82,2,78 };
	QuickSortNonR(arr, 0, sizeof(arr) / sizeof(int) - 1);
	Print(arr, sizeof(arr) / sizeof(int));
}



int main()
{
	testQuickSort4();
	testQuickSortNonR();
	return 0;
}

归并排序的递归实现

void Merge(int *arr,int *temp,int begin,int end)
{
	if (begin >= end)
		return ;
	int mid = (begin + end) / 2;
	Merge(arr, temp, begin, mid);
	Merge(arr, temp, mid+1, end);
	int begin1 = begin, end1 = mid;
	int begin2 = mid+1, end2 = end;
	int index = begin;
	while (begin1 <= end1&&begin2<=end2)
	{
		if (arr[begin1] < arr[begin2])
			temp[index++] = arr[begin1++];
		else
			temp[index++] = arr[begin2++];
	}
	while (begin1 <= end1)
	{
		temp[index++] = arr[begin1++];
	}
	while (begin2 <= end2)
	{
		temp[index++] = arr[begin2++];
	}
	memcpy(arr+begin, temp+begin, (end2 - begin + 1)*sizeof(int));
}
void MergeSort(int* arr, int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	Merge(arr, temp, 0, n-1);
	free(temp);
}

归并排序的非递归实现

void MergeSortNonR(int* arr,int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc fail");
		return;
	}
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i+=2 * gap)
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			if (begin2 >=n)
				break;
			if (end2 >=n);
				end2 = n-1;
			int index = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (arr[begin1] < arr[begin2])
					temp[index++] = arr[begin1++];
				else
					temp[index++] = arr[begin2++];
			}
			while (begin1 <= end1)
			{
				temp[index++] = arr[begin1++];
			}
			while (begin2 <= end2)
			{
				temp[index++] = arr[begin2++];
			}
			memcpy(arr + i, temp + i,(end2-i+1)*sizeof(int));
		}
		gap *= 2;
	}
	free(temp);
}

归并排序的测试

void testMergeort()
{
	int arr[] = { 6,1,5,9,4,5,666,9,12,3,99,82,2,78 };
	MergeSort(arr, sizeof(arr) / sizeof(int));
	Print(arr, sizeof(arr) / sizeof(int));
}

void testMergeSortNonR()
{
	int arr[] = { 6,1,5,9,4,5,666,9,12,3,99,82,2,78 };
	MergeSortNonR(arr,sizeof(arr) / sizeof(int));
	Print(arr, sizeof(arr) / sizeof(int));
}

int main()
{

	testMergeort();
	testMergeSortNonR();
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值