快速排序算法的实现
简介
快速排序算法是一种冒泡排序的优化版
能做到在冒泡排序基础上降低时间复杂度的效果。
第一步:
写出将单个元素排列至指定位置的函数
仅提供非递归实现
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;
}

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

被折叠的 条评论
为什么被折叠?



