各种排序代码实现

40 篇文章 0 订阅
13 篇文章 0 订阅

基于C语言实现的

其中堆排序和循环快排使用到栈。
stack.h:

#pragma once

typedef int STDataType;

typedef struct Stack
{
	STDataType* arr;
	int size;
	int capacity;
}Stack;
void StackInit(Stack* s, int capacity);
void StackPush(Stack* s,STDataType data);
void StackPop(Stack* s);
STDataType StackTop(Stack* s);
int StackEmpty(Stack* s);
int StackSize(Stack* s);
int StackCapacity(Stack* s);
void StackDestroy(Stack* s);
void CheckCapacity(Stack* s);

stack.c:

#include "stack.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>

void StackInit(Stack* s,int capacity) {
	assert(s);
	s->arr = (STDataType*)malloc(sizeof(STDataType)*capacity);
	if (s->arr == NULL)
	{
		assert(0);
		return;
	}
	s->capacity = capacity;
	s->size = 0;
}
void StackPush(Stack* s,STDataType data) {
	assert(s);
	if (s->capacity == s->size)
	{
		CheckCapacity(s);
	}
	s->arr[s->size++] = data;
}
void StackPop(Stack* s) {
	assert(s);
	if (StackEmpty(s))
		return;
	s->size -= 1;
}
STDataType StackTop(Stack* s) {
	assert(s);
	return s->arr[s->size-1];
}
int StackEmpty(Stack* s) {
	assert(s);
	return s->size == 0;
}
int StackSize(Stack* s) {
	assert(s);
	return s->size;
}
int StackCapacity(Stack* s) {
	assert(s);
	return s->capacity;
}
void StackDestroy(Stack* s) {
	if (s->arr) {
		free(s->arr);
	}
	s->capacity = 0;
	s->size = 0;
}
void CheckCapacity(Stack* s) {
	assert(s);
	int newcapacity = 2 * s->capacity;
	STDataType* pTemp = (STDataType*)malloc(sizeof(STDataType)*newcapacity);
	if (pTemp == NULL) {
		assert(0);
		return;
	}
	for (int i = 0; i < s->size; i++) {
		pTemp[i] = s->arr[i];
	}
	free(s->arr);
	s->arr = pTemp;
	s->capacity = newcapacity;
}

Sort.h文件:

#pragma once

//时间复杂度:O(N^2)
//空间复杂度:O(1)
//稳定性;稳定
//冒泡排序
void BubbleSort(int arr[], int len);
//应用场景;数据量小,接近有序
//时间复杂度:O(N^2)
//空间复杂度:O(1)
//稳定性;稳定
//插入排序
void InsertSort(int arr[], int len);
void InsertSort1(int arr[], int left, int right)//应用场景:数据量大,无序
//时间复杂度:O(N^1.25 -1.6N^1.25)
//空间复杂度:O(1)
//稳定性;不稳定
//希尔排序
void ShellSort(int arr[], int len);
//时间复杂度:O(N^2)
//空间复杂度:O(1)
//稳定性;稳定
//选择排序
void SelectSort(int arr[], int len);
void SelectSort1(int arr[], int len);
//时间复杂度:O(NlogN)
//空间复杂度:O(1)
//稳定性:不稳定
//大堆升序,小堆降序
//Top  k
//堆排序
void HeapSort(int arr[], int len);

//时间复杂度:O(NlogN)
//空间复杂度:O(N)
//稳定性:不稳定
//优化后的快排
void QuickSort(int arr[], int left, int right);

void MergeData(int arr[], int left, int  mid, int  right,int* temp);
//时间复杂度:O(NlogN)
//空间复杂度:O(N)
//稳定性:稳定
//归并排序   封装对外接口
void MergeSort(int arr[], int len);
void _MergeSort(int arr[], int left, int right,int* temp);
void MergeSortNor(int arr[], int len);

//时间复杂度:O(N)
//空间复杂度:O(N)
//稳定性:稳定
//计数排序
void CountSort(int arr[], int len);
//优化分割  三数取中法
int GetMiddleIndex(int arr[], int left, int right);
//三种分割区间方法
int Partion1(int arr[], int left, int right);
int Partion2(int arr[], int left, int right);
int Partion3(int arr[], int left, int right);

Sort.c:

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <string.h>
//打印函数
void PrintfArray(int arr[],int len) {
	for (int i = 0; i < len;++i) {
		printf("%d ",arr[i]);
	}
	printf("\n");
}
//交换函数
void Swap(int* a, int* b) {
  	     int tmp = *a;
		 * a = *b;
		 * b = tmp;
} 


//时间复杂度:O(N^2)
//空间复杂度:O(1)
//稳定性;稳定
int flag = 0;//0表示没有排序好  //稍加优化的冒泡排序                                                                                                                         |~                        
void BubbleSort(int arr[], int len) {
	
	   flag = 1;
	   for (int i = 0; i < len; i++) {
	       for (int j = len - 1; j > i; j--) {
		       if (arr[j - 1] > arr[j]) {				
			           flag = 0; 
			           Swap(&arr[j - 1],&arr[j]); 		
				}			
			}
		} 		
	}

//时间复杂度:O(N^2)
//空间复杂度:O(1)
//稳定性;稳定

void InsertSort(int arr[], int len) {
	for (int i = 1; i < len; ++i) {
		//待插入元素
		int key = arr[i];
		//找key的插入位置:与前面已经排好的元素比较
		int end = i - 1;
		while (end >= 0 && key < arr[end]) {
			arr[end + 1] = arr[end];
			end -= 1;
		}
		//插入元素
		arr[end + 1] = key;
	}
}

//时间复杂度:O(N^1.25 -1.6N^1.25)
//空间复杂度:O(1)
//稳定性;不稳定

void ShellSort(int arr[], int len) {
	int gap = len;
	while (gap>0) {
		gap = gap / 3 + 1;//O(N^1.25 -1.6N^1.25)时间复杂度
		for (int i = gap; i < len; ++i) {
			//待插入元素
			int key = arr[i];
			//找key的插入位置:与前面已经排好的元素比较
			int end = i - gap;
			while (end >= 0 && key < arr[end]) {
				arr[end + gap] = arr[end];
				end -= gap;
			}
			//插入元素
			arr[end + gap] = key;
		}
		gap -= 1;
	}
}

//堆排序向下调整
void AdjustDown(int arr[], int len, int parent) {
	int child = parent * 2 + 1;
	while (child < len) {
		if (child + 1 < len && arr[child + 1] > arr[child]) {
			child += 1;
		}			
		if (arr[child] > arr[parent]) {
				Swap(&arr[child], &arr[parent]);
				parent = child;
				child = parent * 2 + 1;
		}
			else
				return;		
	}
}

//时间复杂度:O(NlogN)
//空间复杂度:O(1)
//稳定性:不稳定
//Top  k

void HeapSort(int arr[],int len) {
	//建堆找倒数第一个非叶子节点
	int root = ((len - 2) >> 1);
	for (; root >= 0; --root) {
		AdjustDown(arr, len, root);
	}
	//排序  堆删除思想
	int end = len - 1;
	while (end) {
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, end, 0);
		end--;
	}
}




//缺陷:进行了重复比较
void SelectSort1(int arr[], int len) {
	
	for (int i = 0; i < len - 1;++i) {
		int Maxpos = 0;
		for (int j = 1; j < len - i;++j) {
			if (arr[j] > arr[Maxpos]) {
				Maxpos = j;
			}
			if(Maxpos != len-i-1)
			Swap(&arr[len-i-1], &arr[Maxpos]);
		}
	}
}
//时间复杂度:O(N^2)
//空间复杂度:O(1)
//稳定性;稳定
void SelectSort(int arr[], int len) {
	int begin = 0;
	int end = len - 1;
	while (begin<end) {
		int Maxpos = begin;
		int Minpos = begin;
		int index = begin+1;
		while (index<=end) {
			if (arr[index] > arr[Maxpos])
				Maxpos = index;
			if (arr[index] < arr[Minpos])
				Minpos = index;
			index++;
		}
		if (Minpos == end)
			Minpos = Maxpos;
		//可能会覆盖小元素位置,所以要更新Minpos位置
		
		if (Maxpos != end)
			Swap(&arr[Maxpos], &arr[end]);
		
		if (Minpos != begin)
			Swap(&arr[Minpos], &arr[begin]);
		begin++;
		end--;
	}

}

//优化分割  三数取中法 


int GetMiddleIndex(int arr[], int left, int right) {

	int mid = left + ((right - left) >> 1);
	if (arr[left] < arr[right - 1]) {
		if (arr[mid] < arr[left])
			return left;
		else if (arr[mid] > arr[right - 1])
			return right - 1;
		else
			return mid;
	}
	else {
		if (arr[mid] > arr[left])
			return left;
		else if (arr[mid] < arr[right - 1])
			return right - 1;
		else
			return mid;
	}
}

//分割方式
//第一种:hoare
int Partion1(int arr[], int left, int right) {
	int begin = left;
	int end = right-1;
	int mid = GetMiddleIndex(arr, left, right);
	Swap(&arr[mid], &arr[right - 1]);
	int key = arr[right-1];

	while (begin<end) {

		while (begin < end && arr[begin] <= key)
			begin++;
		while (begin < end && arr[end] >= key)
			end--;
		if(begin != end)
		Swap(&arr[begin], &arr[end]);
	}
	if(begin != right-1)
	Swap(&arr[right - 1], &arr[begin]);
	return begin;
}


//第二种:挖坑法
int Partion2(int arr[], int left, int right) {
	int begin = left;
	int end = right - 1;
	int mid = GetMiddleIndex(arr, left, right);
	Swap(&arr[mid], &arr[right - 1]);
	int key = arr[right - 1];
	while (begin<end) {
		while (begin < end && arr[begin] <= key)
			begin++;
		if (begin < end) {
			arr[end] = arr[begin];
			end--;
		}
		while (begin < end && arr[end] >= key)
			end--;
		if (begin < end) {
			arr[begin] = arr[end];
			begin++;
		}
	}
	arr[begin] = key;
	return begin;
	
}
//第三种:两个指针
int Partion3(int arr[], int left, int right) {
	int cur = left;
	int pre = cur - 1;
	int mid = GetMiddleIndex(arr, left, right);
	Swap(&arr[mid], &arr[right - 1]);
	int key = arr[right - 1];
	while (cur < right) {
		if (arr[cur] < key && ++pre != cur)
			Swap(&arr[pre], &arr[cur]); 
		cur++;
	}
	if(++pre != right)//防止越界
	Swap(&arr[pre], &arr[right - 1]);
	return pre;
}

void QuickSort(int arr[], int left, int right) {
	//[  )左闭右开
	if (right-left>1) {
		//分割左右区间
		int div = Partion3(arr, left, right);
		QuickSort(arr, left, div);
		QuickSort(arr, div + 1, right);
	}

}

//优化快排实现(相互配合)的调用接口
//修改的插入排序

void InsertSort1(int arr[], int left, int right) {
	for (int i = left; i < right; ++i) {
		//待插入元素
		int key = arr[i];
		//找key的插入位置:与前面已经排好的元素比较
		int end = i - 1;
		while (end >= 0 && key < arr[end]) {
			arr[end + 1] = arr[end];
			end -= 1;
		}
		//插入元素
		arr[end + 1] = key;
	}
}

//应用场景(数据量大,随机序列)
//优化之后的快排
//三数取中法
//减小递归深度 数据长度小于16时,用直接插入排序替换
//时间复杂度:O(NlogN)
//空间复杂度:O(N)
//稳定性:不稳定
void QuickSort1(int arr[], int left, int right) {
	//[  )左闭右开
	if (right - left < 16)
		InsertSort1(arr, left, right);
	else {
		//分割左右区间
		int div = Partion3(arr, left, right);
		QuickSort1(arr, left, div);
		QuickSort1(arr, div + 1, right);
	}

}
#include "stack.h"
void QuickSortNor(int arr[],int len) {
	int left = 0;
	int right = len;

	Stack s;
	StackInit(&s,len);
	StackPush(&s, right);
	StackPush(&s, left);
	int div = Partion3(arr, left, right);
	while (!StackEmpty(&s)) {
		left = StackTop(&s);
		StackPop(&s);
		right = StackTop(&s);
		StackPop(&s);
		if (right - left > 1) {
			int div = Partion3(arr, left, right);
			//[left,div)
			//[div+1,right)
			//保存右半部分
			StackPush(&s, right);
			StackPush(&s, div + 1);
			//保存左半部分
			StackPush(&s, div);
			StackPush(&s, left);
		}
	}
}

void MergeData(int arr[],int left,int  mid,int  right,int* temp) {
	int begin1 = left, end1 = mid;
	int begin2 = mid, end2 = right;
	int index = left;
		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++];
}


void _MergeSort(int arr[], int left, int right,int* temp) {
	if (right - left > 1) {
		int mid = left + ((right - left) >> 1);
		//[left,mid)
		//[mid,right)
		_MergeSort(arr, left, mid,temp);
		_MergeSort(arr, mid, right,temp);
		MergeData(arr, left, mid, right,temp);
		memcpy(arr+left, temp+left, sizeof(int)*(right - left));
	}
}

void MergeSort(int arr[], int len) {
	int* temp = (int*)malloc(sizeof(int)*len);
	if (NULL == temp) {
		assert(0);
		return;
	}
	_MergeSort(arr, 0, len, temp);
	free(temp);
}
//时间复杂度:O(NlogN)
//空间复杂度:O(N)
//稳定性:稳定
void MergeSortNor(int arr[], int len) {
	int* temp = (int*)malloc(sizeof(int)*len);
	if (NULL == temp) {
		assert(0);
		return;
	}
	int gap = 1;
	while (gap < len) {
		for (int i = 0; i < len; i += 2 * gap) {
			int left = i;
			int mid = left + gap;
			if (mid >= len)
				mid = len;
			int right = mid + gap;
			if (right >= len)
				right = len;
			MergeData(arr, left, mid, right, temp);
		}
		memcpy(arr, temp, sizeof(int)*len);
		gap *= 2;
	}
	free(temp);
}

void CountSort(int arr[],int len) {
	//找数据范围
	int minvalue = arr[0];
	int maxvalue = arr[0];
	for (int i = 0; i < len;++i) {
		if (arr[i] >= maxvalue)
			maxvalue = arr[i];
		if (arr[i] < minvalue)
			minvalue = arr[i];
	}
	int range = maxvalue - minvalue + 1;
	
	int* pCount = (int*)malloc(sizeof(int)*range);
	if (NULL == pCount) {
		assert(0);
		return;
	}
	memset(pCount, 0, sizeof(int)*range);
	//统计元素出现个数
	for (int i = 0; i < len;++i) {
		pCount[arr[i] - minvalue]++;
	}
	//回收元素
	int index = 0;
	for (int i = 0; i < range;++i) {
		while (pCount[i]) {
			arr[index++] = i + minvalue;
			pCount[i]--;
		}
	}
	free(pCount);
}


int main() {
					
		//int  arr[] = { 3,5,2,9,1,7,6,0,8,4 }; 
		//int  arr[] = { 2,5,1,7,4,6,9,3,8,0 };
		//int  arr[] = { 3,4,2,9,1,7,6,0,8,5 };
		int  arr[] = { 2,1,2,5,4,1,2,1,5,4,2,5,4,1,5,2,4,2,1,5,1,4,5,5,4 };
		PrintfArray(arr, sizeof(arr) / sizeof(arr[0]));
	    //BubbleSort(arr, sizeof(arr) / sizeof(arr[0]));
		//InsertSort(arr, sizeof(arr) / sizeof(arr[0]));
		//ShellSort(arr, sizeof(arr) / sizeof(arr[0]));
		//SelectSort1(arr, sizeof(arr) / sizeof(arr[0]));
		//SelectSort(arr, sizeof(arr) / sizeof(arr[0]));
		//QuickSort(arr, 0,sizeof(arr) / sizeof(arr[0]));
		QuickSort1(arr, 0, sizeof(arr) / sizeof(arr[0]));
		//MergeSort(arr, sizeof(arr) / sizeof(arr[0]));
		//MergeSortNor(arr, sizeof(arr) / sizeof(arr[0]));
		//CountSort(arr, sizeof(arr) / sizeof(arr[0]));
		//HeapSort(arr, sizeof(arr) / sizeof(arr[0]));
		//QuickSortNor(arr, sizeof(arr) / sizeof(arr[0]));
		PrintfArray(arr, sizeof(arr) / sizeof(arr[0]));
	    return 0; 
}

测试结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值