快速排序算法的实现

这篇博客详细介绍了快速排序算法的非递归实现方法,通过三数去中法选择基准值,并使用挖坑法优化排序过程。作者首先定义了部分排序函数`partsort`,然后展示了如何使用栈来存储区间端点,实现非递归的快速排序。这种方法降低了空间复杂度,提高了排序效率。

快速排序算法的实现

简介

快速排序算法是一种冒泡排序的优化版
能做到在冒泡排序基础上降低时间复杂度的效果。

第一步:

写出将单个元素排列至指定位置的函数
仅提供非递归实现

int partsort(int* a, int first, int last) {
//first和last不一定为数组的左右位置,
//而是划分的区间的左右位置
//使用三数去中法,降低取到的基准值为最大值或最小值的概率
	int mid;
	mid = (first + last) /2;
	if (a[first] > a[mid]) {
		if (a[last] < a[mid]) {
			swap(a, first, mid);
		}
		if (a[first] > a[last] && a[last] > a[mid]) {
			swap(a, first, last);
		}
	}
	if (a[first] < a[mid]) {
		if (a[last] > a[mid]) {
			swap(a, mid, first);
		}
		if (a[last] < a[mid] && a[first] < a[last]) {
			swap(a, last, first);
		}
	}
	//利用挖坑法让元素到达指定位置能减少swap函数使用,提高效率
	int temp = a[first];
	int i=first;//将i和j想成两个指针
	int j=last;
	while (i != j) {
	//两指针向中间移动,经过循环,比基准值大的被分配到右边
	//i==j时,全部分配完毕,并且i就是基准值应该排列的位置
//用于测试,请省略该行	printf("%d\n%d\n", i, j);
		for (; temp <= a[j] && i != j; j--);
		a[i] = a[j];
		for (; a[i] <= temp && i != j; i++);
		a[j] = a[i];
	}
	a[i] = temp;//让基准值到达排列正确的位置
}

第二步

非递归实现

非递归实现具有优越性,降低递归所带来的空间复杂度
基本思想:
没有递归导致左右两边的排列,无法同时进行
利用栈的后进先出功能,存储区间的左右端点下标

void quicksort(int* a, int n) {
	int first = 0;
	int last = n - 1;//取出左右端点
	int divide = 0;//用于存储基准值位置,也是区间的分割点
	int* e = (int*)malloc(sizeof(int));
	if (!e)return;
	//初始化栈
	linkstackptr s = (linkstackptr)malloc(sizeof(linkstack));
	if (!s)return;
	s->top = NULL;
	s->count = 0;
	//进行入栈操作
	push_linkstack(s, first);
	push_linkstack(s, last);
	while (isempty_linkstack(s) == 0) {
	//栈不为空,可以说代表区间未分割完
		pop_linkstack(s,e);
		last= *e;
		pop_linkstack(s,e);
		first= *e;
		//出栈,用出栈元素作为区间端点
		divide=partsort(a, first, last);
		//存储右区间端点
		if (divide + 1 < last) {
			push_linkstack(s, divide + 1);
			push_linkstack(s, last);
		}
		//存储左区间端点,在下一循环进行使用
		if (first < divide - 1) {
			push_linkstack(s, first);
			push_linkstack(s, divide);
		}
	}
}

一些辅助函数和需要用到的头文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef enum Status {
	SUCCESS = 1, ERROR = 0
}status;
typedef struct Linklist {
	int data;
	struct Linklist* next;
}linklist;
typedef struct Linkstack {
	linklist* top;
	int count;
}linkstack, * linkstackptr;
//检查是否为空栈
status isempty_linkstack(linkstack* s) {
	if (s->count == 0) {
		return SUCCESS;
	}
	else {
		return ERROR;
	}
}
//出栈并带出出栈值
void pop_linkstack(linkstack* s,int*e) {
	if (s->count==0) return;
	int temp = s->top->data;
	linklist* p = (linklist*)malloc(sizeof(linklist));
	if (!p)return ERROR;
	p = s->top;
	s->top = s->top->next;
	free(p);
	p = NULL;
	s->count--;
	*e = temp;
	return;
}
//入栈
status push_linkstack(linkstack* s, int e) {
	linklist* p = (linklist*)malloc(sizeof(linklist));
	if (!p)return ERROR;
	p->data = e;
	p->next = s->top;
	s->top = p;
	s->count++;
}
void swap(int* a, int m, int n) {
	int temp;
	temp = a[m];
	a[m] = a[n];
	a[n] = temp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值