快速排序的非递归实现

快速排序的递归方法在之前的博客之中已经讲过,接下来给大家介绍非递归的方法。将递归方法转换为非递归的方法时,一般会想到使用循环,但是一些算法仅仅靠循环是非常难的。这时可以考虑使用各种数据结构,比如栈,二叉树,堆等。快速排序非递归的方法则可以通过栈来实现。

我之前写的关于快速排序递归方法的讲解:
https://mp.csdn.net/mp_blog/creation/editor/123786370

关于栈的基本操作:

typedef int STDataType;
typedef struct Stack
{
	STDataType* _a;
	int _top;		// 栈顶
	int _capacity;  // 容量 
}Stack;

void StackInit(Stack* ps) {
	ps->_a = (STDataType*)malloc(sizeof(STDataType) * 3);
	ps->_top = 0;
	ps->_capacity = 3;
}
//检查栈是否还有空间
void CheckCapacity(Stack* ps) {
	if (ps->_capacity == ps->_top) {
		int newcapacity = ps->_capacity * 2;
		STDataType* temp = (STDataType*)malloc(newcapacity * sizeof(STDataType));
		if (NULL == temp) {
			return;
		}
		memcpy(temp, ps->_a, sizeof(STDataType) * ps->_capacity);
		free(ps->_a);
		ps->_a = temp;
	}
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps) {
	assert(ps);
	if (ps->_top == 0) {
		return 1;
	}
	return 0;
}
// 入栈 
void StackPush(Stack* ps, STDataType data) {
	CheckCapacity(ps);
	ps->_a[ps->_top] = data;
	ps->_top++;
}
// 出栈 
void StackPop(Stack* ps) {
	if (StackEmpty(ps))
		return;
	ps->_top--;
}
// 获取栈顶元素 
STDataType StackTop(Stack* ps) {
	if (StackEmpty(ps))
		return 0;
	return ps->_a [ps->_top - 1];
}

根据之前将过的,快速排序的三种方法:

  1. hoare法
  2. 挖坑法
  3. 前后指针法
// 快速排序hoare版本
int PartSort1(int* a, int left, int right) {
	int begin = left;
	int end = right-1;
	int key = a[left];//关键字的取值为a[dir]即a[begin],最左侧的元素
	while (begin < end) {
		while (begin<end&&a[end] >= key) {
			end--;
		}
		while (begin<end&&a[begin] <=key) {
			begin++;
		}
		if (begin != end) {
			int temp = a[begin];
			a[begin] = a[end];
			a[end] = temp;
		}
	}
	int tem = a[begin];
	a[begin] = a[left];
	a[left]= tem;
	return begin;//返回关键字的下标
}

// 快速排序挖坑法
int PartSort2(int* a, int left, int right) {
	int begin = left;
	int end = right-1;
	int key = a[left];
	while (begin < end) {
		while (begin < end && a[end] >= key) {
			end--;
		}
		if (begin < end) {
			a[begin] = a[end];
			begin++;
		}
		while (begin < end && a[begin] <= key)
			begin++;
		if (begin < end) {
			a[end] = a[begin];
			end--;
		}
	}
	a[begin] = key;
	return begin;
}
// 快速排序前后指针法,基准值取值为最右侧元素
int PartSort3(int* a, int left, int right) {
	int cur = left;
	int prev = cur - 1;
	int key = a[right-1];
	while (cur < right) {
		if (a[cur] < key && ++prev != cur) {
			int temp = a[cur];
			a[cur] = a[prev];
			a[prev] = temp;
		}
		cur++;
	}
	if (++prev != right - 1) {
		int temp = a[prev];
		a[prev] = a[right-1];
		a[right-1] = temp;
	}
	return prev;
}

下面是具体实现快速排序非递归的代码:


void QuickSortNonR(int* a, int left, int right) {
	Stack st;
	StackInit(&st);
	StackPush(&st, left);
	StackPush(&st, right-1);
	while (StackEmpty(&st)!=1) {
		int _end = StackTop(&st);
		StackPop(&st);
		int _begin = StackTop(&st);
		StackPop(&st);
		int div = PartSort1(a, _begin, _end+1);
		if (_begin < div ) {
			StackPush(&st, _begin);
			StackPush(&st, div);
		}
		if (div + 1 < _end) {
			StackPush(&st, div + 1);
			StackPush(&st, _end);
		}
	}
}

使用时直接调用即可,举例:

void main() {
	int a[] = {5,6,4,3,7,2,8,1,9,0};
	int n = sizeof(a) / sizeof(a[0]);
	QuickSortNonR(a, 0, n );
	//打印排序好的数组
	for (int i = 0; i < n; i++) {
		printf("%d ", a[i]);
	}
	printf("\n");
}

快速排序的非递归实现_第1张图片

你可能感兴趣的:(笔记,c语言,数据结构,排序算法)